Testowanie metodą Fault Injection

| Technika

Problem testowania układów elektronicznych jest istotną kwestią, jaką trzeba rozwiązać przy okazji tworzenia każdego projektu układu scalonego. Odpowiednie przygotowanie procesu testowania staje się coraz ważniejsze. Niniejszy artykuł omawia technikę testowania, jaką jest wstrzykiwanie błędów - Fault Injection. Testowanie układów elektronicznych staje się trudniejsze wraz z postępem technologicznym. Coraz większe układy wykonywane w coraz nowocześniejszych procesach technologicznych mogą zawierać wiele błędów, z których części czasami nie da się uniknąć.

Testowanie metodą Fault Injection

Duża złożoność układów sprawia, że modelowanie błędów i ich wykrywanie jest bardzo utrudnione i niemożliwe bez odpowiednio wydajnych narzędzi. W rozwiązaniu sytuacji nie pomaga fakt, że kolejne generacje układów wypierają poprzednie, nawet co kilka miesięcy. Tak duże tempo produkcji wymaga zatrudnienia dużej liczby inżynierów, którzy podzieleni są na grupy zajmujące się poszczególnymi elementami układu. Ogrom rozmiarów najnowszych projektów powoduje, że zazwyczaj nie istnieje żadna osoba, która byłaby w stanie objąć umysłem cały projekt i efektywnie przeglądać działanie projektowanego układu w poszukiwaniu potencjalnych przyczyn błędów. Jednym ze sposobów na redukcję błędów w działaniu układów jest stosowanie strategii „dziel i rządź” i implementowanie mechanizmów zabezpieczeń, detekcji i korekcji błędów oddzielnie w poszczególnych partiach układu. Niestety, nie pozwala to na zabezpieczenie całego układu oraz nie jest sposobem na przetestowanie rezultatów wystąpienia potencjalnych pomyłek technologicznych.

Ochrona przed skutkami błędów

Znaczenie powyższych rozważań nie zmieniło się od ponad 10 lat. Inżynierowie świadomi konsekwencji wprowadzenia na rynek układów wadliwych, bądź takich, które są bardzo wrażliwe na wszelkie niedokładności pojawiające się podczas procesu technologicznego zaczęli łączyć ze sobą dwa sposoby postępowania: projektowanie systemów z zabezpieczeniami oraz testowanie gotowych układów. Należy zauważyć, że obecnie obie te techniki są ze sobą ściśle powiązane. W dużych układach nie da się efektywnie projektować systemów detekcji i korekcji błędów bez możliwości sprawdzania ich efektywności. Dzieje się tak dlatego, że zarówno czasy propagacji sygnałów jak i wzajemny wpływ poszczególnych elementów układu scalonego znacząco utrudniają rozważania na temat skuteczności zastosowanych mechanizmów tolerancji błędów. Testowanie pozwala więc ocenić na ile dobry jest gotowy wyrób oraz ułatwia projektowanie.

Jedną z technik testowania układów projektowanych jako odporne na błędy jest Fault Injection, czyli wstrzykiwanie błędów. Metoda ta polega na symulowaniu wystąpienia niepoprawnego działania lub wprowadzania uszkodzeń do wnętrza projektowanego układu scalonego i może być realizowana na kilka sposobów. Pierwszym z nich jest fizyczne wywołanie uszkodzeń w gotowym urządzeniu. Niestety technika ta ma bardzo wiele wad i chyba tylko jedną zaletę - pozwala na pracę nad takim układem, jaki ostatecznie trafia do sprzedaży - czyli jest najbardziej wiarygodna. Niestety jest też bardzo czasochłonna i przede wszystkim kosztowna. Koncentrując się na projektowaniu układów ASIC (Application Specific Integrated Circuit) należy zauważyć, że wyprodukowanie prototypu wymaga czasu związanego z przygotowaniem procesu technologicznego, co wiąże się z bardzo dużymi kosztami. Trudno jest też testować kilka różnych rozwiązań zabezpieczeń jednocześnie, gdyż każde z nich wymagałoby stworzenia oddzielnego prototypu. Wprowadzanie istotnych poprawek wymaga zazwyczaj wykonania kolejnego prototypu, co wydłuża czas projektowania i generuje dodatkowe koszty. Co więcej, wstrzykiwanie błędów do gotowego układu jest procesem skomplikowanym. O ile zazwyczaj nie stanowi problemu podawanie niepoprawnych lub zakłóconych sygnałów na wejścia (albo i wyjścia) układu, to kwestia implantacji błędów do wnętrza półprzewodnika, jest już niezmiernie kłopotliwa. Jednym z wykorzystywanych w tym celu sposobów jest uszkadzanie przez napromieniowywanie układu promieniowaniem o dużej energii. Powoduje ono losowe zmiany w ładunkach zgromadzonych np. w zintegrowanych komórkach pamięci SRAM, FLASH lub też w przerzutnikach. Niestety, z racji swej natury jest to metoda trudna do kontrolowania, mało dokładna i dosyć kosztowna. O ile wysoka dawka promieniowania może w ostateczności prowadzić do przepalenia podsystemów w układzie, uszkodzenia te nie symulują w pełni wszystkich możliwych defektów typowych dla procesu technologicznego CMOS. Z powyższych względów metoda testowania gotowego układu scalonego może być tylko w pewnym zakresie nazywana wstrzykiwaniem błędów, a jej użyteczność jest ograniczona.

Fot. 1. Urządzenie do testowania układów scalonych poprzez ich napromieniowywanie.

Drugim sposobem testowania poprzez wprowadzanie błędów jest podawanie ich z poziomu programu. Gotowy układ scalony instalowany jest na odpowiednio przygotowanej płycie uruchomieniowej, na której instalowany jest również system operacyjny. Po uruchomieniu systemu układ wprowadzany jest w taki tryb pracy, aby możliwe było wykonywanie typowych zadań przeznaczonych dla danego układu scalonego oraz pełen dostęp do pamięci urządzenia. Działający w ten sposób układ poddawany jest testom, które polegają na wprowadzaniu błędów do poszczególnych obszarów pamięci oraz do danych (sygnałów) generowanych przez usługi systemowe. Niestety metoda ta pozwala jedynie na wprowadzanie błędów, do których dostęp ma uruchomiony program oraz nie umożliwia testowania ich wystąpienia w ciągu wykonywanych instrukcji. Jest to więc metoda wtórna i zawodna, choć nie wymaga wielu nakładów. Oczywiście, aby jej użyć konieczne jest wyprodukowanie prototypu, ale ze względu na koszt jej organizacji i typ wykrywanych błędów jest ona stosowana jako dodatkowa weryfikacja poprawności działania.

Prawdziwe wstrzykiwanie

Trzecią metodą jest przeprowadzanie pełnych symulacji działania układu za pomocą innego systemu komputerowego. Dopiero ta metoda jest w pełni zgodna z definicją sformułowania Fault Injection. Prawdziwie wstrzykiwanie błędów powinno być techniką testowania wiarygodności układu z tolerancją błędów poprzez kontrolowane eksperymenty, podczas których obserwowane jest zachowanie układu w obecności precyzyjnie wygenerowanych i wprowadzonych usterek. Technika wykorzystująca symulację ma przewagę nad pozostałymi. Po pierwsze do jej zastosowania nie jest konieczne fizyczne wyprodukowanie układu scalonego. Oznacza to, że może być ona wykorzystywana interaktywnie i faktycznie stosowana w trakcie opracowywania projektu. Brak konieczności produkowania wielokrotnych prototypów to również sposób na uniknięcie ogromnych kosztów związanych z procesami technologicznymi. Symulacja pozwala także na precyzyjne indukowanie błędów, a więc weryfikowanie tych fragmentów układu, które chcą sprawdzić projektanci w dowolnie wybranych warunkach działania.

Podejście symulacyjne może być realizowane na kilku poziomach abstrakcji. Układ można symulować na poziomie elektrycznym, na poziomie bramek albo na poziomie przesłań międzyrejestrowych. Najbardziej dokładna metoda pozwala na testowanie dowolnego typu błędów i zachowanie pełnej kontroli nad całym układem. Nieco mniej złożona polega na badaniu podatności na błędy logiczne, dyskretne - choć niekoniecznie cyfrowe, gdyż nieograniczone przez kwantyzację czasu. Natomiast poziom przesłań RTL pozwala na badanie fragmentów układu jako całych, połączonych ze sobą podzespołów. Wymaganiem, które należy spełnić, aby możliwe było zastosowanie symulacji jest przygotowanie odpowiedniego kodu VHDL. Jednakże zazwyczaj nie jest to problemem, gdyż wielokrotnie jest on częścią projektu, a w licznych innych przypadkach można go automatycznie wygenerować na podstawie np. narysowanej topologii układu scalonego.

W wyborze wersji wstrzykiwania błędów przez symulację kryje się największa wada tego podejścia - czasochłonność. Precyzyjne symulacje na poziomie elektrycznym wymagają bardzo dużej liczby obliczeń, a w związku z tym zaawansowanych komputerów i czasu. W praktyce badania na wyższych poziomach abstrakcji są również bardzo wymagające, ze względu na wysoki stopień zaawansowania obecnie projektowanych układów elektronicznych. Naukowcy w wielu instytutach pracują nad technikami usprawniania procesu symulacyjnego, a niektóre opracowane dotąd metody zostaną omówione w dalszej części artykułu. Zanim to nastąpi konieczne jest zapoznanie się z naturą błędów, jakie mogą się pojawić w układach scalonych.

Typy i skutki błędów

Rys. 1. Przyczyny powstawania błędów stanu nieokreślonego

Aby rzetelnie przeprowadzić jakiekolwiek testowanie układu scalonego konieczna jest znajomość możliwych błędów, jakie występują w układach scalonych. Błędy te mogą być podzielone na różne kategorie. Mogą być to błędy: logiczne, czasowe, logiczno-czasowe i elektryczne. Pierwsze z nich polegają na zmianie stanu logicznego na przeciwny do tego, który w danym miejscu układu powinien wystąpić, gdyby układ działał prawidłowo. Błędy czasowe związane są zazwyczaj z opóźnieniami i polegają na pojawieniu się odpowiedniego sygnału, ale w nieodpowiednim momencie czasowym, co także może prowadzić do niepoprawnego działania. Błędy logiczno-czasowe to np. pojawienie się błędnej wartości (wymuszenia błędnej wartości) na linii w momencie zupełnie nieoczekiwanym, a błędy elektryczne to różnego rodzaju wahania napięć i niestabilności.

Wymienione grupy mogą mieć różne przyczyny i w różny sposób się objawiać. Najprostszym w modelowaniu jest błąd typu „stuck-at”, czyli zwarcie danej linii sygnałowej do masy lub do zasilania - ewentualnie do poziomu logicznego zera lub jedynki, w przypadku gdy wartości te różne są od napięć zasilania. Szacuje się, że błędy te stanowią około 60% wszystkich błędów występujących w układach produkowanych w technologii CMOS. O ile wartość ta jest względnie duża, należy zaznaczyć, że wiele z technik projektowania ogranicza się jedynie do uwzględniania i zapobiegania tylko tego typu pomyłkom, czego efektem są niezabezpieczone w pełni układy. Wśród pozostałych 40% znajdują się błędy logiczne takie jak zwarcie ze sobą linii oraz błędy elektryczne - np. rozwarcie linii, pojawianie się stanu nieustalonego i wpływ sygnału jednej linii na drugą (rys. 1 i rys. 2). Wraz ze wspomnianymi wcześniej błędami opóźnieniowymi i błędami danych w komórkach pamięci stanowią one razem grupę błędów określanych potocznie mianem sabotażu. Drugą grupą błędów są mutacje, których efektem jest zmiana algorytmu wykonywanego przez cyfrowy układ scalony.

Wstrzykiwanie poszczególnych błędów wymaga wykorzystania możliwości symulatora i np. języka VHDL. Błąd „stuck_at” w VHDL generowany jest przez przypisanie danej linii wartości 0 lub 1, błąd rozwartej linii przypisaniem wartości Z, a stanu wysokiej impedancji poprzez przypisanie linii wartości X. Aby uniknąć konieczności każdorazowego rekompilowania układu, przy próbie wprowadzenia dowolnego błędu należy zastosować odpowiedni symulator pozwalający na pracę w trybie debuggowania. Przydatne może być również zastosowanie bibliotek elementów, które zawierają dodatkowe moduły pozwalające na sterowanie wyprowadzanymi z nich sygnałami. Dostępność takich bibliotek na rynku jest niewielka, gdyż są one tworzone głównie na potrzeby badań naukowych, w związku z czym projektant zmuszony jest zazwyczaj samemu stworzyć potrzebną mu bibliotekę.

Rys. 2. Przyczyny powstawania błędów rozwartej ścieżki

Projektant powinien również znać efekty, jakie może spowodować wprowadzona usterka. Po pierwsze może ona nie aktywować żadnego błędu, tzn. nie wpływać na pracę układu. Bardzo często usterki wpływają tylko na niektóre zadania wykonywane przez układ, toteż proces testowania powinien być tak zaprojektowany, by urządzenie wykonywało jak najwięcej różnych operacji. Błąd aktywowany przez usterkę może być następnie wykryty lub nie. Jeżeli nie zostanie wykryty, to urządzenie będzie działać niepoprawnie, a użytkownik może o tym nie wiedzieć. Jeżeli błąd jest detekowalny, to urządzenie może podjąć próbę naprawienia go, o ile zostało wyposażone w takie mechanizmy. Jeżeli próba się powiedzie, urządzenie działa poprawnie, ale w przypadku, gdy danego błędu nie da się naprawić, urządzenie zgłasza, że uzyskiwany wynik działań jest niepoprawny. Schemat ten przedstawiony został na rysunku 3. W szczególnym przypadku powstały błąd może zostać aktywowany, ale nie będzie wykrywany albo też nie spowoduje żadnego efektu przez pewien czas, po czym wpłynie na wynik dopiero po pewnej liczbie taktów. Jest to bardzo prawdopodobna sytuacja we wszystkich układach, które nie są układami kombinacyjnymi.

Rys. 3. Możliwe efekty wystąpienia usterki

Błędy mogą być wprowadzane do układu w dwóch postaciach - jako sygnały i jako zmienne. Aby w pełni kontrolować proces wstawiania błędów konieczna jest implementacja w symulatorze kilku funkcji. Funkcje te to „symuluj do...”, „modyfikuj sygnał...”, „symuluj przez...”, „odtwórz sygnał...” i „przypisz wartość...”. Na koniec, przed uruchomieniem symulacji należy ustalić liczbę i typ wstrzykiwanych błędów, zaplanować momenty ich wprowadzenia, czas trwania oraz miejsca, w których się pojawią. Ze względu na dużą wartość liczby wstrzykiwanych błędów koniecznych do pełnego przetestowania układu dane te ustala się często drogą losową tak, aby rola projektanta ograniczyła się jedynie do zadania podstawowych wytycznych.

Optymalizacja testowania

Opisana technika Fault Injection - o ile bardzo skuteczna, jest bardzo czasochłonna, toteż stosuje się pewne usprawnienia, które pozwalają na ograniczenie liczby usterek, jakie należy wstrzykiwać, by w pełni przetestować układ. Przykładowo, procent wykrywanych błędów rośnie ekspotencjalnie wraz ze zróżnicowaniem czasów trwania wstrzykiwanych błędów. Gdyby wszystkie czasy trwania błędów były identyczne, prawdopodobnie część błędów nie zostałaby wykryta, np. ze względu na różnego rodzaju pętle występujące wewnątrz algorytmów wykonywanych przez urządzenie. Pętle te mogłyby przykryć znaczenie błędów trwających np. zbyt krótko. Ponadto moment wstrzykiwania błędów też ma wpływ na ich aktywację i detekowalność. Okazuje się, że najmniej błędów uaktywnia się, gdy są jednostajnie, losowo rozmieszczone w przeciągu całego czasu symulacji. Znacznie więcej usterek aktywuje błędy, gdy występują jedna po drugiej lub nawet na raz. Innym usprawnieniem może być dzielenie błędów na kategorie i wprowadzanie tylko niewielkich grup usterek reprezentujących poszczególne kategorie. Grupowanie ma na celu redukcję liczby wstrzyknięć, a co za tym idzie i czasu symulacji, dzięki założeniu, że usterki z danej grupy mogą spowodować ten sam błąd w analogiczny sposób. Opracowano także sposób na sprawniejsze wykrywanie błędów, które ujawniają się dopiero po jakimś czasie od wprowadzenia usterki. Z przeprowadzonych badań wynika, że błędy na wyjściu układu pojawiają się najczęściej albo od razu, albo dopiero z dużym opóźnieniem i gdy już wystąpią, powodują stale niepoprawną pracę urządzenia. W związku z tym zaleca się poszukiwanie opóźnionych błędów po 2n cyklach zegarowych od momentu wprowadzenia usterki, zamiast co cykl.

Innym możliwym do realizacji usprawnieniem testowania w oparciu o symulacje programowe jest próba zrównoleglenia obliczeń za pomocą klastrów komputerowych oraz analiza rezultatów metodami odkrywania wiedzy. Pewne osiągnięcia w tej dziedzinie mają również polscy naukowcy z Politechniki Warszawskiej, którzy z powodzeniem rozwijają i stosują tego typu system w celach naukowych.

A może użyć FPGA?

Rys. 4. Architektura systemu testowania FIFA

Innym bardzo ciekawym podejściem do zagadnienia testowania układów ASIC jest wykorzystanie struktur FPGA jako symulatorów - a właściwie prototypów projektowanych układów. Dostępne obecnie na rynku układy programowalne są na tyle wydajne, że mogą skutecznie reprezentować wiele z projektowanych układów scalonych. Po wgraniu do nich kodu projektu oraz dzięki zastosowaniu odpowiedniej platformy testowej tworzą one bardzo szybkie narzędzie sprawdzania wpływu kolejnych usterek. Przykładem może być platforma zaprezentowana jakiś czas temu przez naukowców z Politechniki Turyńskiej. Według przeprowadzonych kilka lat temu badań, FIFA - Fault Injection by means of FPGA (tak została nazwana platforma) okazała się nawet ponad 1100 razy szybsza niż metoda testowania opierająca się o komercyjne symulatory VHDL. Na platformę FIFA składa się część sprzętowa oraz oprogramowanie, które uruchamiane jest na nadzorującym testowanie komputerze. Logiczny schemat blokowy platformy został przedstawiony na rysunku 4.

Do uruchomienia platformy konieczny jest syntezowalny kod VHDL na poziomie RTL oraz gotowy zestaw sygnałów pobudzeń układu wykorzystywanych w trakcie procesu testowania. Ważne jest, aby sygnały te wzbudzały jak najwięcej obliczeń oraz odwołań do układów wejścia/wyjścia. Na płytce drukowanej platformy FIFA znajduje się układ FPGA oraz interfejs przekazywania błędów do i z komputera. Procedurę testowania uruchamia komputer, na którym pracują trzy moduły programowe: procedura zarządzania listą usterek, moduł zarządzania wstrzykiwaniem błędów i analizator rezultatów. Najwięcej działań wykonuje moduł wstrzykiwania, gdyż to on odpowiada za komunikację z interfejsem płytki drukowanej. Tymczasem analizator rezultatów przydziela kategorie poszczególnym błędom.

Na protokół komunikacyjny składają się polecenia Step - wykonaj jedną instrukcję, Run - wykonaj kilka instrukcji, Evaluate - zwróć określone dane do komputera, Inject - wprowadź usterkę i Tick, które powoduje podanie do układu jednego taktu zegarowego. Na płytce znajduje się specjalna szyna interfejsu, która oddziela testowany układ od otaczających go podzespołów, jak również oddziela rdzeń układu wewnątrz FPGA od jego zewnętrznych rejestrów. Bardzo istotnym elementem konstrukcji platformy FIFA jest szybki interfejs pomiędzy układem FPGA, a pamięcią RAM. Dzięki temu możliwe jest wstrzykiwanie serii błędów w sposób wsadowy, odbierając wyniki zapisywane do pamięci RAM tylko co jakiś czas. Pozwala to na maksymalne przyspieszenie procesu testowania. Także i w tej metodzie możliwe jest zastosowanie wielu z opisanych w poprzednim dziale usprawnień.

Rys. 5. Architektura oprogramowania GOOFI

GOOFI – Generic Object-Oriented Fault Injection Tool, to środowisko programowe służące do przeprowadzania testów metodą Fault Injection poprzez symulacje komputerowe badanego układu. Narzędzie zostało zaprojektowane przez naukowców ze Szwecji jako zestaw prostych funkcji pozwalających na przeprowadzanie różnego typu symulacji uwzględniających kilka z podejść do programowego wstrzykiwania błędów. W trakcie tworzenia programu skoncentrowano się na przenośności narzędzia i prostocie obsługi za pomocą interfejsu graficznego. Program został napisany w pełni obiektowo w języku Java, a gromadzone dane przechowywane są w standardowych bazach danych obsługiwanych poprzez polecenia języka SQL. Dodawanie nowej techniki testowania realizowane jest poprzez dopisanie odpowiedniej klasy w języku Java i podłączenie jej do przycisków w menu. Schemat blokowy narzędzia został przedstawiony na rysunku 5.

Czym jest jeszcze Fault Injection?

Poza testowaniem projektów układów ASIC technika wstrzykiwania błędów znajduje także zastosowanie w innych dziedzinach elektroniki, jak i w informatyce. Przykładem może być testowanie odporności układów SRAM FPGA, na pojedyncze błędy w postaci zamiany wartości logicznych w komórkach konfiguracyjnych lub w przerzutnikach. Pozwala to na wykrycie efektów zmian w matrycach LUT, które są jednymi z najbardziej podatnych na tego typu usterki. Przykładowo, zmiana pojedynczego bitu komórki SRAM definiującej połączenia powoduje najczęściej zmianę funkcji logicznej realizowanej przez dany fragment układu. Jedną z najczęściej stosowanych w tym przypadku technik jest testowanie radiacyjne, głównie ze względu na to, że charakteryzuje się ono bardzo dużym pokryciem wykrywanych błędów.

Innym zastosowaniem Fault Injection jest np. testowanie oprogramowania systemów, które muszą wykazywać się wysoką wiarygodnością.

Zastosowania komercyjne

Opisane w artykule techniki to tylko niektóre z proponowanych metod testowania odporności układów scalonych. Poza nimi istnieje wiele innych, mniej popularnych, które często są odmianami tych omówionych. Co jakiś czas powstają nowe projekty mające na celu usprawnienie technik testowania przy wykorzystaniu najnowszych osiągnięć technologicznych. Ich skuteczność zazwyczaj zależy od konkretnego przypadku, na którym są stosowane, toteż wciąż trudno o nowoczesny i uniwersalny komercyjny system testowania. Można mieć tylko nadzieję, że niebawem luka ta zostanie wypełniona jakimś nowym produktem, dzięki któremu projektowanie wiarygodnych układów cyfrowych stanie się łatwiejsze.

Marcin Karbowniczek