wprowadzenie - kik

advertisement
KONCEPCJA REFAKTORYZACJI KODU W JĘZYKU VHDL
Przemysław Sołtan
Politechnika Koszalińska, Wydział Elektroniki, ul. Śniadeckich 2, 75-543 Koszalin
e-mail: [email protected]
Streszczenie
W pracy zaproponowano koncepcję realizacji refaktoryzacji kodu programu zapisanego w
języku VHDL. Refaktoryzacja, czyli zmiana struktury kodu bez zmiany jego zachowania, jest
korzystną i często stosowaną metodą automatycznego tworzenia, modyfikacji i optymalizacji kodów
programów obiektowych JAVA, C++, itd. Specyfika języka VHDL wymusza jednak stosowania
odmiennych od znanych mechanizmów refaktoryzacji, uwzględniających m.in. typy danych nie
występujące w językach programowania obiektowego (np. sygnały, porty, entity, architektury) oraz
brak podstawowych struktur danych – klas. Stosowanie refaktoryzacji projektów VHDL pozwala nie
tylko na zmiany nazw zmiennych różnych typów, funkcji i procesów, zamianę instrukcji,
wyszukiwanie nieużywanego kodu, modyfikacje mapowania portów w komponentach, lecz nawet na
podział procesów przy równoległym przetwarzaniu, co w dużym stopniu wpływa na efektywność
syntezy logicznej projektu VHDL. Zaproponowana koncepcja jest oparta o abstrakcyjne drzewo
składni języka VHDL i jest realizowana w postaci autorskiej biblioteki VDT. Aplikacja VDT
opracowana jest w języku JAVA i współpracuje z platformą ECLIPSE.
1. WPROWADZENIE
Współczesne środowiska projektowe VHDL wspierają projektantów udostępniając im
mechanizmy automatycznej generacji kodu, a część zagadnień związanych z semantyką kodu
jest rozpatrywana na etapie jego symulacji. Brak jest jednak drugiego podejścia, jakim jest
refaktoryzacja istniejącego już kodu oraz badania jego semantyki podczas procesu edycji.
Termin refaktoryzacja definiuje się jako mechanizm zmiany struktury kodu bez zmiany
jego zachowania. Przykładem może być zmiana nazwy zmiennej, zamiana części kodu, czy
też ekstrakcja fragmentu kodu do nowej zewnętrznej funkcji lub komponentu.
Ręczna refaktoryzacja kodu jest procesem czasochłonnym, a tym samym podatnym na
występowanie błędów podczas jego realizacji. Z tego względu warto zautomatyzować ten
proces poprzez tworzenie niezawodnych i wydajnych narzędzi wspierających projektantów w
realizacji tego zadania. Jest to niezbędnym warunkiem, aby refaktoryzacja mogła stać się
powszechnie przyjętą techniką tworzenia i pielęgnacji programów.
Projekt VHDL
(przed refaktoryzacją)
PARSER
(drzewo AST)
Polecenie
refaktoryzacji
Biblioteka do
refaktoryzacji
Projekt VHDL
(po refaktoryzacji)
Aktualizacja
widoku
Widok Użytkownika
Edytor
Rys. 1. Proces programowej refaktoryzacji kodu VHDL.
W tym celu należy opracować mechanizmy: analizy kodu źródłowego, budowania modelu
oraz zintegrowanego z nim edytora umożliwiającego pobieranie poleceń refaktoryzacji od
użytkownika systemu. Schemat blokowy takiego systemu został przedstawiony na rys. 1.
W niniejszej pracy przedstawiono refaktoryzację w kontekście języka VHDL. Odmienność
przekształceń refaktoryzacji języka VHDL względem innych języków polega na braku
obiektowych aspektów języka wykorzystywanych przy refaktoryzacji. Mechanizmy
obiektowe jako pierwszy opisał w 1992 roku Opdyke [1], brak jest jednak prac dotyczących
zagadnień języka VHDL.
Zastosowanie języka VHDL jako języka opisu sprzętu wymaga innego podejścia do
zagadnienia refaktoryzacji ze względu na różnorodność typów danych oraz występowanie
fragmentów kodu równoległego przetwarzania.
2. PRZYKŁAD PROSTEGO PRZEKSZTAŁCENIA REFAKTORYZACJI
Elementarnym przykładem zastosowania mechanizmów refaktoryzacji jest zmiana
nazwy jednego z elementów w kodzie projektu. W przypadku obiektowych języków
programowania takich jak Smalltalk, Java czy też C++ mamy do czynienia z takimi
podstawowymi elementami jak zmienne, funkcje oraz klasy.
W przypadku języka VHDL dostępnych jest o wiele większa liczba elementarnych typów
nazw [2]. Wyszczególnić można takie elementy jak nazwy: zmiennych, sygnałów, portów,
entity czy też architektur. Każdy z elementów wymaga wykonania odmiennych działań.
entity entityOldName is
entityNewName
port(in1 : in bit; out1 : out bit);
end entityOldName ;
architecture architectureName1 of entityOldName is
begin
-- code
end architectureName1;
architecture architectureName2 of entityOldName is
begin
-- code
end architectureName2;
------------------------------------------entity entityTestName is
port(in1 : in bit; out1 : out bit);
end entityTestName;
ENTITY
ARCHITECTURE
...
ARCHITECTURE
COMPONENT
PORT MAP
...
architecture architectureTestName of entityTestName is
component entityOldName
port(in1 : in bit; out1 : out bit);
end component ;
begin
comp1: entityOldName port map (in1,out1);
-- rest of port map component
end architectureTestName;
Rys. 2. Przykładowy kod VHDL (zmiana nazwy entity).
Na rysunku rys. 2. przedstawiono przykładowy kod z uwzględnieniem elementów, które
należy zmienić przy zmianie nazwy entity przykładowej jednostki projektowej.
Proces zmiany nazwy entity wymusza realizację kilku elementarnych operacji:
- wskazanie elementu określającego starą nazwę entity (entityOldName);
- określenie nowej nazwy entity (entityNewName);
-
sprawdzenie, czy nowa nazwa nie koliduje z już istniejącymi nazwami;
wyszukanie bloku danego entity (zmiana nazwy);
wyszukanie architektur dla danego entity (zmiana nazwy);
wyszukanie w blokach architektur komponentów danego entity (zmiana nazwy);
wyszukanie wszystkich mapowań komponentów danego entity (zmiana nazwy).
Może wydawać się, że do wykonania takiej prostej operacji jak zmiana nazwy entity
wystarczy zwykła operacja zamiany łańcuchów tekstu dostępna w środowiskach edycyjnych.
Wymaga to jednak od projektanta podejmowania decyzji, czy dany łańcuch tekstowy jest
powiązany z danym elementem, którego nazwę zamierzamy zmienić. Ma to szczególne
znaczenie, przy deklarowaniu elementów o takich samych nazwach (np. takich samych
nazwach portów różnych komponentów). Sytuacja jeszcze bardziej się komplikuje, gdy mamy
do czynienia z wieloma plikami należącymi do tego samego projektu. Może to powodować
błędy i utratę integralności otrzymanego projektu po dokonaniu modyfikacji. Z tego względu
cały proces można zautomatyzować i w ten sposób odciążyć projektanta od podejmowania
części decyzji. Wymaga to jednak analizy kodu na poziomie syntaktycznym i tworzenia
modelu projektu przy pomocy składniowego drzewa AST.
3. DRZEWO AST
Abstrakcyjne drzewo składni AST (ang. Abstract Syntax Tree) służy do syntaktycznej
analizy kodu źródłowego napisanego w języku VHDL. AST definiuje węzły reprezentujące
istniejące elementy dostępne w specyfikacji VHDL Syntax (IEEE Std 1076-1993).
AST
E ENTITY (name: entityOldName )
P PORT (name:in1,type:in,type2:bit)
P PORT (name:out1,type:out,type2:bit)
A ARCHITECTURE (name:architectureName1,entity: entityOldName )
A ARCHITECTURE (name:architectureName2,entity: entityOldName )
E ENTITY (name:entityTestName)
P PORT (name:in1,type:in,type2:bit)
P PORT (name:out1,type:out,type2:bit)
A ARCHITECTURE (name:architectureTestName,entity:entityTestName)
C COMPONENT (name: entityOldName )
P PORT (name:in1,type:in,type2:bit)
P PORT (name:out1,type:out,type2:bit)
entityNewName
I INSTANCE (name:comp1, type: entityOldName )
M MAP (from:in1, to:in1)
M MAP (from:out1, to:out1)
Rys. 3. Drzewo AST dla przykładu zmiany nazwy entity.
Kod implementujący drzewo AST zawiera metody umożliwiające poruszanie się po
strukturze drzewa w celu przeanalizowania kodu źródłowego. Dodatkowo należy
zaimplementować kod umożliwiający: wyszukiwanie, wstawianie, usuwanie, przenoszenie
oraz zmianę poszczególnych węzłów drzewa. Przykładowe drzewo AST przedstawiono na
rys. 3. Każdy z węzłów przechowuje informacje o określonym typie przechowanych danych
oraz węźle rodzica i węzłach podrzędnych.
4. ZŁOŻONA REFAKTORYZACJA KODU VHDL
Metody refaktoryzacji kodu nie dotyczą tylko zmiany nazw poszczególnych zmiennych.
Można realizować inne przekształcenia np. zamiany kodu instrukcji if na instrukcję case,
wyszukiwanie nieużywanego kodu, modyfikacje mapowania portów w komponentach, czy
też podział procesów przy równoległym przetwarzaniu. Złożone modyfikacje nie powinny
wpływać na funkcjonowanie modelu VHDL, ale mogą mieć wpływ na efektywność kodu w
procesie syntezy. Wskazane jest więc opracowanie katalogu wzorców refakoryzacji [3] dla
języka VHDL opartych o opis wzorca, motywację, mechanizm i przykłady. Jest to dobry
kierunek dalszych badań nad mechanizmami refaktoryzacji kodu w języku VHDL.
Realizacja złożonych refaktoryzacji wymusza także implementacje dodatkowych
funkcji takich jak: transakcyjność i praca na kopii roboczej modyfikowanych danych.
Transakcyjność polegająca na analizie poprawności elementarnych operacji i zatwierdzeniu
całości po pomyślnej realizacji każdej z nich. Praca na kopii roboczej daje możliwość
wycofania zmian i określania różnic (tzw. delty) dokumentów przed i po refaktoryzacji kodu.
EDYTOR
Projekt VHDL
PLIK1.vhd
PLIK2.vhd
MODEL
BIBLIOTEKI
AST
STANDARD
PLIK3.vhd
IEEE
Rys. 4. Projekt VHDL jako model.
Na rys. 4. przedstawiono schemat struktury projektu rozpatrywanej jako model danych
drzewa AST. Pliki projektu są powiązane z modelem wzajemną relacją. Oznacza to, że
zmiana zawartości pliku za pomocą edytora wymusza aktualizacje modelu zawierającego
drzewo AST. Podobnie zmiana któregoś z węzłów drzewa AST wymusza aktualizacje
widoku w edytorze kodu. Dla plików należących do bibliotek relacja jest jednostronna –
zbudowane drzewo AST na podstawie danych z biblioteki jest dostępne tylko do odczytu.
5. PLATFORMA ECLIPSE I PROJEKT VDT (VHDL DEVELOPMEN TOOLKIT)
Autorski projekt VDT jest aktualnie w stadium eksperymentalnym. Zaprojektowana
biblioteka zrealizowana w języku JAVA umożliwia tworzenie drzewa AST na podstawie
plików źródłowych projektu VHDL.
ECLIPSE PLATFORM
VDT PROJECT
CORE
SCANNER
PARSER
AST
MODEL
WORKBENCH
PDE
UI
EDITOR
OUTLINE
Rys. 5. Architektura eksperymentalnego systemu refaktoryzacji kodu VHDL zintegrowanego z
platformą ECLIPSE.
Część kodu odpowiedzialna za analizę kodu wygenerowano przy pomocy odpowiedniej
gramatyki vhdl.jjt i programu JavaCC (Java Compiler Compiler) [4].
Otrzymany kod został zintegrowany z platformą ECLIPSE [5], wykorzystując jego
funkcjonalność. Zaletą tego rozwiązania jest możliwość wykrywania błędów podczas edycji
kodu – (skaner kodu działa w tle i w sposób dynamiczny wskazuje niepoprawne elementy
składniowe). Na tym etapie następuje przyspieszenie projektowania, co jest nową jakością
znaną z narzędzi IDE najnowszej generacji takich jak ECLIPSE. Architekturę
eksperymentalnego systemu refaktoryzacji kodu przedstawiono na rys. 5.
Wybór darmowej platformy ECLIPSE zaprojektowanej przez firmę IBM przy użyciu
języka JAVA umożliwia wieloplatformowość, czyli pracę środowiska projektowego na
różnych systemach operacyjnych. Za wyborem platformy przemawia także fakt bogactwa
rozwiązań programistycznych wspierających środowisko przy użyciu tzw. wtyczek (ang.
plug-in). W ten sposób w jednym pakiecie projektowym możliwe jest integrowanie różnych
rozwiązań.
Na rys. 6. zaprezentowano widok środowiska projektowego. Zaimplementowano analizę kodu
wraz z systemem zgłaszania błędów syntaktycznych.
Rys. 6. Edytor kody VHDL oparty o platformę ECLIPSE.
Projekt eksperymentalnej biblioteki VDT posiada status otwartego oprogramowania (Open
Source) i jest oparta o licencję CPL - http://www.eclipse.org/legal/cpl-v10.html, podobnie jak
cała platforma ECLIPSE i jej podprojekty JDT dla JAVY i CDT dla C++ wspierające
mechanizmy refaktoryzacji.
Projekt VDT dostępny jest pod adresem http://kik.ie.tu.koszalin.pl/mvl/vdt.
6. KIERUNKI ROZWOJU PROJEKTU
Rozwój metod refaktoryzacji opartych o model danych w postaci drzewa AST może
być wspierany przez dodatkowe mechanizmy. Nieodłącznym elementem refaktoryzacji jest
weryfikacja kodu przed i po jej wykonaniu. Oba testy powinny uzyskiwać taki sam wynik.
Aby to sprawdzić należy przygotować odpowiednie testy – testBenches. Ten proces można
wspomagać stosując autorską bibliotekę testów jednostkowych vhdlUnit [6]. Posiadając
kontrolę nad kodem w postaci modelu danych można zaimplementować mechanizm iniekcji
(wstrzykiwania) kodu testów. W ten sposób uzyskać częściowo zautomatyzowany mechanizm
testowania.
Innym ważnym czynnikiem jest możliwość generacji dokumentacji HTML
powiązanych odnośnikami (mechanizm wzorowany na JavaDOC ze środowiska Java).
Pożądaną właściwością jest stworzenie narzędzia wspierającego refaktoryzację dla
języka Verilog i innych języków z jednoczesnym wykorzystaniem VHDL. Uzyskana
kombinacja różnych języków w jednym projekcie prowadzi jednak do wzrostu złożoności
kodu źródłowego. Do tego dochodzi jeszcze analiza schematów udostępnianych w różnych
niestandardowych formatach (bde, sch, edif). Być może wskazane jest opracowanie
wspólnego opisu ich odwzorowania w formacie XML wraz z konwerterami ich importu i
eksportu (bde2xml, sch2xml, edif2xml).
Wyzwaniem jest również zaprojektowanie takich mechanizmów, które ułatwią
konwertowanie modeli niesyntezowalnych w ich wersje syntezowalne. Wymagać to może
wykorzystania podczas przekształceń refaktoryzacji własnych modeli lub zewnętrznych
modeli tzw. IPCore’ów.
Zagadnienie refaktoryzacji przez projektantów platformy ECLIPSE [7] zostało
potraktowane bardzo poważnie. Z tego względu w jego nowej wersji zaprojektowano
specjalistyczną bibliotekę LTK – Eclipse Language Toolkit wspierającą mechanizmy
refaktoryzacji dla innych języków programowania. Implementacja tego mechanizmu do
języka VHDL jest częścią dalszych badań prowadzonych przez autora niniejszej publikacji.
7. PODSUMOWANIE
Refaktoryzacja jako nowa dziedzina w analizie i przetwarzaniu kodu źródłowego ma
kluczowe znaczenie, ponieważ ułatwia zarządzanie coraz bardziej złożonym kodem
tworzonych projektów. Dodatkowo, mechanizmy stosowane w środowisku ECLIPSE
umożliwiają wykrywanie błędów syntaktycznych na poziomie edycji kodu, a nie w fazie
kompilacji realizowanej podczas symulacji, czy syntezy.
W pracy zaprezentowano tylko jeden prosty przykład dokonywania refaktoryzacji kodu.
Wskazane jest opracowanie katalogu wzorców refakoryzacji dla języka VHDL opartych o
opis wzorca, motywację, mechanizm i przykład. Jest to dobry kierunek dalszych badań i
rozwoju eksperymentalnego projektu VDT jako praktycznej realizacji mechanizmów
refaktoryzacji kodu VHDL.
LITERATURA I ŹRÓDŁA
[1] Opdyke B., „Refactoring Object-Oriented Frameworks”, University of Illinois at UrbanaChampaign, 1992
[2] Rushton A., Vhdl for logic synthesis, John Wiley & Sons, 1998
[3] katalog wzorców refaktoryzacji - http://www.refactoring.com
[4] projekt JavaCC – http://www.experimentalstuff.com/Technologies/JavaCC
[5] platforma ECLIPSE - http://www.eclipse.org
[6] P. Sołtan, „Koncepcja realizacji testów jednostkowych w języku VHDL”. Prace VII Konferencji
Krajowej „Reprogramowalne układy cyfrowe”, RUC’2004, Szczecin, 2004, pp. 117-124.
[7] Shavor S., D’Anjou J., Fairbrother S., Kehn D., Kellerman J., McCarthy P., „Eclipse Podręcznik
programisty”, Helion, 2005
CONCEPT OF REFACTORING IN VHDL
Przemysław Sołtan
Technical University of Koszalin, Department of Electronics, Ul. Sniadeckich 2, 75-453 Koszalin
e-mail: [email protected]
Abstract
In this paper, the conception of the refactorization of programs represented in VHDL language
is proposed. Refactorization (refactoring), which means the purposed introduce of changes in
the program source code without changes in its behavior, is the powerful and often used method
for automatic generation, modification and optimization of object sources represented in Java,
C++ and other programming languages. However, the specific of the VHDL language needs to
use specific and unknown refactoring mechanisms, which takes to account the data types
absented in the above programming languages (for example, signals, ports, entities,
architectures, etc.) and do not operate with the main object data structures – classes. The
proposed conception is based on the abstract syntax tree of the VHDL language and is realized
as the VDT Java application with the original author’s library. The application is destined for
operating in the ECLIPSE platform.
Download