コード例 #1
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}");
            }
        }
コード例 #2
0
        internal static unsafe (UnsafeMemory <BitState> bits, bool isValidBinary) ToBitStates(ReadOnlySpan <byte> valueText, BitAllocator bitAlloc)
        {
            UnsafeMemory <BitState> bitsMem = bitAlloc.GetBits(valueText.Length);
            Span <BitState>         bits    = bitsMem.Span;

            ulong isValidBinary = 0;
            int   index         = 0;

            if (Ssse3.IsSupported && bits.Length >= Vector128 <byte> .Count)
            {
                int vecBitCount = bits.Length / Vector128 <byte> .Count;
                fixed(BitState *bitsPtr = bits)
                {
                    fixed(byte *textPtr = valueText)
                    {
                        Vector128 <ulong> isValidBin = Vector128 <ulong> .Zero;

                        for (; index < vecBitCount; index++)
                        {
                            var charText = Avx.LoadVector128(textPtr + index * Vector128 <byte> .Count);
                            var byteText = Avx.Shuffle(charText, shuffleIdxs);

                            var firstBit         = Avx.And(onlyFirstBit, Avx.Or(byteText, Avx.ShiftRightLogical(byteText.AsInt32(), 1).AsByte()));
                            var secondBit        = Avx.And(onlySecondBit, Avx.ShiftRightLogical(byteText.AsInt32(), 5).AsByte());
                            var bytesAsBitStates = Avx.Or(firstBit, secondBit);

                            Avx.Store((byte *)bitsPtr + bits.Length - (index + 1) * Vector128 <byte> .Count, bytesAsBitStates);
                            isValidBin = Avx.Or(isValidBin, secondBit.AsUInt64());
                        }

                        isValidBinary = isValidBin.GetElement(0) | isValidBin.GetElement(1);
                    }
                }

                index *= Vector128 <byte> .Count;
            }

            for (; index < bits.Length; index++)
            {
                BitState bit = ToBitState(valueText[index]);
                bits[bits.Length - index - 1] = bit;
                isValidBinary |= (uint)bit & 0b10;
            }

            return(bitsMem, isValidBinary == 0);
        }
コード例 #3
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}");
            }
        }
コード例 #4
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}");
            }
        }
コード例 #5
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);
            }
        }
コード例 #6
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);
        }
コード例 #7
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);
            }
        }