4. Realizacja modułów sprzętowych

4. Realizacja modułów sprzętowych


Do poprawnej komunikacji w systemie została zadeklarowana przestrzeń adresowa dla każdej z płyt. Ze względów opisanych w rozdziale 7.4.1, a dotyczących błędnie działających połączeń elektrycznych, wykorzystano jedynie 16 (z 24) linii adresowych magistrali Wishbone. Przestrzeń adresowa dla każdej z płyt została rozdzielona na następujące moduły sprzętowe:
  • DAC: od 0x0000h do 0x7FFFh;
    - ADC1_RAM : 0x0000h do 0x1003h,
    - ADC2_RAM: 0x2000h do 0x3003h,
    - DAC_RAM: 0x4000h do 0x6FFFh,
    - SPI : 0x7000h do 0x7003h,
    - CLK_DIV : 0x7004 do 0x7007h,
    - DAC_ID_REG : 0x7008h,
    - CLK_DISTRIBUTION_REG : 0x7009h.
  • DIC: od 0x8000h do 0x8FFFh;
    - GPIB_CORE : 0x8000h do 0x8001h,
    - WS_UART : 0x8010h do 0x801Fh,
    - I2C_MASTER_TOP : 0x8020h do 0x8027h,
    - LEDSS : 0x8060h,
    - DIC_ID_REG : 0x8061h.
 

4.1. Zestaw modułów po stronie UMC


Zestaw modułów składa się z 2 części:
  • kontrolera,
  • "przekładni" (HOST_PCI_PLUG) wraz z buforami wej/wyj.
Zestaw został opracowany w dwóch wersjach. Wersja pierwsza wykorzystuje kontroler interfejsu RS232, a wersja druga interfejs USB znajdujące się na płycie UMC. Obie wersje przedstawiono na rysunkach 4.1 i 4.2.
 
Rysunek 4.1. Zestaw modułów po stronie UMC wraz z kontrolerem RS
 

4.1.1. Kontroler systemowy RS


Jako kontroler systemowy, obsługujący interfejs RS232 na płycie UMC, wykorzystano "RS232 system controller" (rs_syscon [39]). Jego działanie opiera się na dekodowaniu trzech instrukcji wysłanych od strony komputera i wykonywaniu ich na magistrali Wishbone:
  • • Zapis: "w aaaaaa dddddddd xx\r"1
    zapis od adresu 24-bitowego aaaaaa, 32-bitowych danych dddddddd, w liczbie xx, zwiększając adres o jeden przy każdym zapisie. Pole liczby odczytów jest opcjonalne i może zostać pominięte wraz z wcześniej występującą spacją, co skutkuje wykonaniem pojedynczego zapisu.
    Każda z liter ‘a’, ‘d’ i ‘x’ oznacza cyfrę zapisaną heksadecymalnie 0..F, a znak \r oznacza znak powrotu karety,
  • Odczyt: "r aaaaaa xx\r" – odczyt danych od adresu 24-bitowego aaaaaa, w liczbie xx słów 32-bitowych, zwiększając adres o jeden przy każdym odczycie. Pole liczby odczytów jest opcjonalne i może zostać pominięte wraz z wcześniej występującą spacją, co skutkuje wykonaniem pojedynczego odczytu,
  • Reset: "i\r" – moduł resetuje urządzenia podłączone podłączone do magistrali Wishbone.

Użyta konfiguracja modułu rs_syscon oraz wartości wraz z krótkim opisem parametrów przedstawiono w tabeli 4.1.
 

Tabela 4.1. Konfiguracja rs_syscon
 
Została wykorzystana możliwość zwracania "echa". Każda komenda uzyskuje potwierdzenie zwrotne w formie swojej kopii, co umożliwiło wyeliminowanie błędów w transmisji poleceń. Błędnie potwierdzona komenda jest wysyłana ponownie w celu uzyskania jej prawidłowego wykonania i potwierdzenia. Przyczynami błędów w transmisji mogą być m.in.:
  • niedokładnie zsynchronizowane zegary wytwarzające tzw. "baudrate",
  • chwilowe zakłócenie transmisji na złączu RS232,
  • niepoprawne podłączenie do złącza.
 

4.1.2. Kontroler systemowy USB

 
Opracowano moduł "virtual_com_usb_syscon" (VCusb) jako kontroler systemowy obsługujący interfejs USB na płycie UMC . Jego działanie opiera się na dekodowaniu trzech instrukcji wysłanych od strony komputera i ich wykonywaniu na magistrali Wishbone. Składnia instrukcji jest podobna do składni dla kontrolera "rs_syscon" (patrz. roz. 4.1.1) z tą różnicą, że nie są dostępne pola liczby odczytów/zapisów. Moduł VCusb składa się z dwóch automatów przedstawionych blokowo na rysunku 4.3.
 
Kontroler steruje układem FT245BM [40], który pełni następujące funkcje na płycie UMC:
  • działa analogicznie do układu UART, zamieniając szeregową transmisję na pojedyncze bajty, umieszczane w kolejce fifo,
  • układ "widziany" jest jako wirtualny port szeregowy COM, co znacznie upraszcza obsługę portu USB od strony programisty.
 

Rysunek 4.3. Schemat blokowy kontrolera USB
 
Zadania automatu "usb_to_wsh" obejmują obsługę linii układu FT245BM oraz dekodowanie instrukcji (wysłanych od strony PC). Po zdekodowaniu instrukcji, sterowanie zostaje przekazanie automatowi "wsh_to_usb", którego zadaniem jest wykonanie zdekodowanej instrukcji na magistrali Wishbone. Po wykonaniu instrukcji sterowanie jest przekazane z powrotem do "usb_to_wsh". Konfiguracja modułu VCusb, użyte wartości i którki opis paramterów, zostały przedstawione w tabeli 4.2.
 

Tabela 4.2. Konfiguracja VCusb
 
 
Algorytm działania automatu "usb_to_wsh" zaprezentowano na rysunku 4.4.
 

Rysunek 4.4. Algorytm działania
 
Z uwagi na zachowanie przejrzystości grafu stanów i warunków przejść, rysunek opisuje pogrupowane stany automatu; np. grupa stanów "read_cmd" składa się z kilku stanów: "read_cmd_state_0", "read_cmd_state_1" itd, a grupa stanów "read_adress" składa się z: "read_adress_state_0", "read_adress_state_1" itd. Stany automatu pogrupowano według pełnionej funkcji:

read_cmd odpowiada za oczekiwanie na poprawna komendę w kodzie ASCII: "w", "r" oraz "i". Litery oznaczają odpowiednio zapis na magistrali Wishbone, odczyt na magistrali Wishbone, wykonanie resetu na magistrali Wishbone. Jeżeli znak nie jest poprawny, to następuje przejście do grupy stanów "command_failure". Poszczególne stany grupy odpowiadają za odpowiednie obsłużenie linii RXF oraz RD (odczyt). Wymagane stany na liniach RD oraz RXF wraz z rygorami czasowymi zostały przedstawione w dokumentacji układu FT245BM,

read_cmd_space odpowiada za odczyt znaku spacji. Jeżeli odczytany znak jest inny, to następuje przejście do grupy stanów "commad_failure". Poszczególne stany grupy odpowiadają za obsłużenie linii RXF oraz RDz,

read_addres odpowiada za odczyt pól adresowych. Jeżeli odczytany znak jest inny niż cyfra heksadecymalna w kodzie ASCII, znak spacji (w przypadku dekodowania komendy zapisu) albo znak powrotu karetki (w przypadku dekodowania komendy odczytu), to następuje przejście do grupy stanów "command_failure". Jeżeli została odczytana maksymalna liczba wymaganych pól adresowych, to przejście automatu zależy od dekodowanej komendy – odczytywanie znaku spacji dla komendy zapisu, odczytywanie znaku powrotu karetki dla komendy odczytu. Kolejne odczytywane pola adresowe są dekodowane z kodu ASCII na liczby binarne za pomocą układu kombinacyjnego i wpisywane (pół-bajtami) do rejestru przesuwnego od strony młodszych bitów.
Poszczególne stany grupy odpowiadają za obsłużenie linii RXF oraz RD,

read_adress_space odpowiada za odczyt znaku spacji. Jeżeli odczytany znak jest inny, to następuje przejście do grupy stanów "commad_failure". Poszczególne stany grupy odpowiadają za obsłużenie linii RXF oraz RD, read_data odpowiada za odczyt pól danych. Jeżeli odczytany znak jest inny niż cyfra heksadecymalna w kodzie ASCII albo znak powrotu karetki, to następuje przejście do grupy stanów "command_failure". Jeżeli została odczytana maksymalna liczba wymaganych pól danych, to następuje przeskok do odczytywania znaku powrotu karetki. Kolejne odczytywane pola danych są dekodowane z kodu ASCII na liczby binarne za pomocą układu kombinacyjnego i wpisywane (pół-bajtami) do rejestru przesuwnego od strony młodszych bitów.
Poszczególne stany grupy odpowiadają za obsłużenie linii RXF oraz RD,

read_return_carret odpowiada za odczyt znaku powrotu karetki. Jeżeli odczytany znak jest inny, to następuje przejście do grupy stanów "commad_failure". Poszczególne stany grupy odpowiadają za obsłużenie linii RXF oraz RD,

start_wishbone odpowiada za przekazanie sterowania automatowi "wsh_to_usb" i oczekiwanie na potwierdzenie zakończenia operacji przez automat "wsh_to_usb" na magistrali Wishbone. Jeżeli operacja nie zakończy się w maksymalnym czasie oczekiwania, to operacja ta zostaje anulowana i następuje przejście do grupy stanów "wsh_busy".
Poszczególne stany grupy "start_wishbone" nie odpowiadają za obsługę układu FT245BM, a za obsługę wewnętrznych sygnałów modułu VCusb (takich jak rdy oraz rec),

wsh_busy odpowiada za wysłanie znaku "!" w kodzie ASCII do PC, informując użytkownika, iż wykonywana instrukcja nie została potwierdzona po stronie Wishbone (linia ack_i nigdy nie została ustawiona w stan aktywny).
Poszczególne stany grupy odpowiadają za obsłużenie linii TXE oraz WR. Wymagane stany na liniach WR oraz TXE, wraz z wymaganiami czasowymi zostały przedstawione w dokumentacji układu FT245BM,

wsh_ack odpowiada za wysłanie znaku "@" w kodzie ASCII do PC, informując użytkownika, iż wykonywana instrukcja została potwierdzona po stronie Wishbone (linia ack_i została ustawiona w stan aktywny przez co najmniej jeden cykl zegarowy).
Poszczególne stany grupy odpowiadają za obsłużenie linii TXE oraz WR,

recive odpowiada za wysyłanie danych do PC, w przypadku gdy została zdekodowana komenda odczytu ("r"). Dane odczytane z magistrali Wisbone są konwertowane z postaci binarnej do heksadecymalnej w kodzie ASCII, a następnie wysyłane. Poszczególne stany grupy odpowiadają za obsłużenie linii TXE oraz WR,

command_failure odpowiada za wysłanie znaku "fi" w kodzie ASCII do PC, informując użytkownika, iż instrukcja nie została poprawnie przez niego wpisana. Po wysłaniu znaku "fi" następuje przejście do grupy stanów "read_cmd" i ponowne oczekiwanie na dalsze komendy.
Poszczególne stany grupy odpowiadają za obsłużenie linii TXE oraz WR.

 

4.1.3. Host_PCI_plug oraz bufory wej/wyj

 
Z powodu problemów sprzętowych zaistniała potrzeba opracowania "przekładni" sygnałów opisanych w specyfikacjiWishbone na sygnały połączeń PMC wykorzystywane w systemie. Wynikało to z faktu, iż nie wszystkie linie sygnałowe (w miejscu połączenia PMC) działały prawidłowo. "Przekładnia" sygnałów została zamieszczona w tabeli 4.3.
 
Tabela 4.3. Przekładnia sygnałów
 
W układzie "HOST_PCI_PLUG" wykorzystano 23 (z 24) linii adresowych. Karty DAC i DIC wykorzystują jedynie pierwsze 16 spośród nich, a pozostałe są programowo ustawiane na logiczne zera.
 
Drugą funkcją modułu "Host_PCI_plug" jest ustawianie na odpowiednich liniach stanu wysokiej impedancji (ukl. wej/weyj typu otwarty dren). Liniami tymi są dwukierunkowe linie PCI_AD[31..] oraz linia PCI_CBE3. Liniami PCI_AD[31..0] przesyłane są dane, a linią PCI_CBE3 propaguje się sygnał "we" (a ang. write enable).
 

4.2. Zestaw modułów po stronie DAC

 
Zestaw modułów po stronie DAC składa się z 9 części:
  1. "Przekładni" (SLAVE_PCI_PLUG) wraz z buforami wej/wyj, do której dołączony jest dodatkowy dekoder adresu (ze względu na złożony sposób działania dekodera Wishbone-Interconnect z biblioteki Altium Designer),
  2. Dekodera adresów Wishbone-Interconnect [41],
  3. ADC1_RAM, sterującego pierwszym przetwornikiem A/C oraz obsługującym przypisaną pamięć temu przetwornikowi,
  4. ADC2_RAM, sterującego drugim przetwornikiem A/C oraz obsługującym przypisaną pamięć temu przetwornikowi,
  5. DAC_RAM, sterującego dwoma przetwornikami C/A oraz obsługującym przypisaną im pamięć,
  6. SPI, kontrolującego interfejs SPI, dzięki któremu konfigurowane są układy dystrybucji zegarów i przetworniki C/A,
  7. CLK_DIV, wstępnie dzielący zegar, który wchodzi na układy dystrybucji zegarów,
  8. DAC_ID_REG, rejestr tylko-do-odczytu zawierającego kod identyfikacji 0x00444143h (3 młodsze bajty posiadają interpretację w kodzie ASCII: "DAC"),
  9. CLK_DISTR_REG, rejestr sterującego równoległymi liniami interfejsu układów konfiguracji i dystrybucji zegarów (układów MAX9452 i AD9512).
Pełny zestaw zaprezentowano na rysunku 4.5.
 
Rysunek 4.5. Zestaw modułów po stronie DAC
 

4.2.1. Slave_PCI_plug oraz bufory wej/wyj

 
Implementacja przekładni Host_PCI_plug po stronie UMC wymagała opracowania przekładni po stronie płyty DAC. Przekładnia Slave_PCI_plug pełni dwie funkcje:
  • "przekłada" sygnały w odwrotną stronę, niż w tabeli 4.3, od strony złącz PMC na sygnały wymagane do komunikacji Wishbone na płycie DAC,
  • steruje buforami wej/wyj od stron płyty DAC.
Po stronie płyty DAC wykorzystano 16 bitów szyny adresowej. Pozostałe linie zadeklarowano jako porty wejściowe w celu wymuszenia stanów wysokiej impedancji na odpowiadających im liniach.
 
Moduł Slave_PCI_plug, podobnie jak Host_PCI_plug na płycie UMC, ustawia odpowiednio stany wysokiej impedancji na liniach dwukierunkowych PCI_AD[31..0]. Dodatkowo stan wysokiej impedancji jest ustawiany na linii PCI_CBE2. Do tej linii, zgodnie z tab. 4.3, jest podpięty sygnał "ack_i", a dla płyty DAC jest to "ack_o" (z ang. acknowledge output). Sygnał "ack_o" jest sygnałem zwrotnym potwierdzenia i wychodzi on z dwóch płyt DAC i DIC. Stąd, w celu uniknięcia kolizji, na linii PCI_CBE2 wymagana jest obsługa bufora 3-stanowego (realizowana w układzie FPGA jako bufor z otwartym drenem). Buforem steruje dodatkowy dekoder adresowy,który zapewnia, że jeśli następuje odwołanie do płyty DIC, to wyjście na linię PCI_CBE2 od strony płyty DAC przechodzi w stan wysokiej impedancji.
 

4.2.2. Kontrolery pamięci i przetworników A/C

 
Kontrolery pamięci i przetworników A/C (ADC1_RAM i ADC2_RAM) zostały zaadoptowane z [10]. Dodano możliwość wyzwalania (z ang. trigger) akwizycji warunkami logicznymi nałożonymi na próbkowany sygnał. Oba kontrolery zostały wykonane podobnie. Niewielkie różnice opisano dalej w tekście. Moduł ADC1_RAM zaprezentowano na rysunku 4.6.
 

Rysunek 4.6. Kontroler pamięci i pierwszego przetwornika A/C – ADC1_RAM
 
Kontroler składa się z 2 głównych części.
  • Pamięci, widzianej od adresu 0x0000h do 0x0FFFh, zorganizowanej w 4096 16-bitowych słów. Do obsługi pamięci zostały użyte gotowe moduły "WB_MEM_CTRL" [42] oraz "RAMDEB" [43] z biblioteki Altium Designer. Pożądaną cechą modułu "RAMDEB" jest dualny dostęp (z ang. Dual-port), co umożliwia łatwe dołączenie jednocześnie od strony kontrolera systemowego i od strony samego przetwornika,
  • Czterech 32-bitowych rejestrów konfiguracji i sterowania układem wyzwalania widzianych od adresu 0x1000h do 0x1003h (0x3000h do 0x3003h dla ADC2_RAM).
Działanie poszczególnych bitów zostało zestawione w tabelach od 4.4 do 4.6 i krótko opisane.
 
Tabela 4.4. Rejestr 0x1000h (0x3000h dla ADC2_RAM)
 
Bit 15 informuje, czy przetwornik podczas konwersji nie uległ przepełnieniu lub niedopełnieniu. Wynik przepełniony i niedopełniony ulega nasyceniu do wartości granicznych w kodzie U2,

Bit 14 informuje, czy układ wyzwalania zakończył operację zbierania wyników. Zbieranie wyników polega na inkrementacji adresu o jeden, wraz z kolejnym cyklem zegarowym ,aż do momentu przepełnienia pamięci. Pod adres ten następuje zapis zebranej przez przetwornik danej. Inkrementacja adresu zaczyna się od momentu spełnienia warunku logicznego, ustawianego przy pomocy bitów 19..16 rejestru spod adresu 0x1002h (0x3002h dla ADC2_RAM). Warunkami logicznymi są porównywania typu >=, >, =, < i <= między wartością chwilową a wartością ustawioną przy pomocy bitów 15..0 rejestru spod adresu 0x1002h
(0x3002h dla ADC2_RAM),

Bity 11..0 (10..0 dla ADC2_RAM) informują jaka jest obecna wartość licznika adresu,

Bit 5 ustawia wew. wzmocnienie przetwornika na 1 albo 1.5. Ustawienie wzmocnienia na 1.5 zmniejsza wartość maksymalnego napięcia wejściowego, przy którym konwerter jeszcze nie nasyca wyników, do 1.5Vp-p,

Bit 4 ustawia wew. randomizację wyników wg. algorytmu Dn := xor(Dn,D0), gdzie n jest numerem bitu z przedziału 15 do 1,

Bit 3 ustawia wew. dither przetwornika,

Bit 2 włącza/wyłącza obwody analogowe przetwornika (odpowiadające za konwersję) oraz włącza/wyłącza cyfrowy interfejs równoległy wprowadzając jego linie w stan wysokiej impedancji,

Bit 1 resetuje licznik adresu,

Bit 0 włącza/wyłącza (sygnał start/stop) układ wyzwalania. Układ wyzwalania jest automatycznie wyłączany w przypadku przepełnienia licznika adresu, powodując iż pojedyncze wyzwolenie akwizycji zbiera 4096 próbek 16-bitowych (2048 dla ADC2_RAM).

 

Tabela 4.5. Rejestr 0x1002h (0x3002h dla ADC2_RAM)
 
Bit 19 potwierdza zakończenie pracy układu wyzwalania. Zakończenie pracy sygnalizowane jest przez bit 14 rejestru spod adresu 0x1000h (0x3000h dla 36ADC2_RAM). Po zakończeniu pracy układu wyzwalania należy pod bit 19 zapisać jedynkę logiczną, a następnie zero logiczne (gdyż bez tego nie będzie możliwe ponowne uruchomienie układu wyzwalania),

Bity 18..16 ustawiają warunek logiczny jaki jest wykorzystywany przy porównywaniu wartości wyzwalania (ww) z chwilową wartością (cw) akwizycji. Wartości od 0x0h do 0x5h kolejno ustawiają warunek: cw >= ww, cw > ww, cw = ww, cw < ww, cw <=. Wartość 0x6h ustala brak warunku, powodujący natychmiastowe uruchomienie licznika adresu w przypadku uruchomienia układu wyzwalania,

Bity 15..0 ustawiają wartość wyzwalania.

 

Tabela 4.6. Rejestr 0x1003h (0x3003h dla ADC2_RAM)
 
Bity 15..0 informują o chwilowej wartości akwizycji, która jest zapamiętywana do rejestru w momencie odczytu tych bitów.

Wszystkie bity w omawianych powyżej rejestrach ustawiane są na zero logiczne wraz z resetemi wraz ze startemsystemu (wgrania strumienia konfiguracyjnego do układu FPGA).

Kontroler drugiego przetwornika oraz jego pamięci (ADC2_RAM) wykonany został podobnie z tą różnicą, iż zostało mu przypisane, ze względu na ograniczoną pamięć układu FPGA, 2k słów 16-bitowych.

 

4.2.3. Kontrolery pamięci i przetworników C/A

 
Kontroler pamięci i przetworników C/A (DAC_RAM) został zaadoptowany z [10]. W zaadoptowanym rozwiązaniu zostały:
  • dodane możliwości resetowania (sprzętowego) przetworników, bez konieczności resetowania całego systemu,
  • dodane możliwości resetowania liczników adresu obu przetworników; obu naraz, wymaganego jeśli należy zsynchronizować sygnały w obu kanałach, oraz każdego z osobna.

Moduł DAC_RAM prezentowany jest na rysunku 4.7.
 

Rysunek 4.7. Kontrolery pamięci i przetworników C/A - DAC_RAM
 
Kontroler składa się z 3 głównych części:
  • Pamięci pierwszego przetwornika, widzianej od adresu 0x4000h do 0x4FFFh, zorganizowanej w 4096 16-bitowych słów. Do obsługi pamięci zostały użyte gotowe moduły "WB_MEM_CTRL" oraz "RAM_DEB" z biblioteki Altium Designer,
  • Pamięci drugiego przetwornika, widzianej od adresu 0x6000h do 0x6FFFh, zorganizowanej i kontrolowanej identycznie jak dla pierwszego przetwornika,
  • 32-bitowych rejestrów konfiguracji i sterowania zarówno układem inkrementacji adresu jak i resetem (sprzętowym) przetworników. Rejestry te widziane są od adresu 0x5000h do 0x5003h. Działanie poszczególnych bitów zostało zestawione w tabelach od 4.7 do 4.8 i krótko opisane.
 

Tabela 4.7. Rejestr 0x5000h
 
Bit 15 jest bitem startu/stopu generacji sygnału na wyjściu przetwornika (pod warunkiem nie włączonego resetu). Generacja sygnału polega na inkrementacji licznika adresu w górę o jeden, wraz z każdym taktem zegara. Adres ten wskazuje na wartość w zadeklarowanej dla przetwornika pamięci. Licznik jest licznikiem modulo, gdzie modulo jest ustalane przez wartość górną licznika adresu,

Bit 14 jest bitem resetującym licznik adresu,

Bity 11..0 ustawiają wartość górną licznika adresu.

Rejestr pisany w tabeli 4.7 zawiera ustawienia dla pierwszego przetwornika. Rejestr spod adresu 0x5001h zawiera identyczne ustawienia dla drugiego przetwornika.

 

Tabela 4.8. Rejestr 0x5003h
 
Bit 1 jest bitem resetu obu liczników adresu. Funkcja taka jest wymagana jeśli należy zsynchronizować generowane sygnały,

Bit 0 jest bitem resetującym przetworniki sprzętowo. Reset sprzętowy resetuje również wew. rejestry konfiguracyjne przetworników.

Wszystkie bity w omawianych powyżej rejestrach ustawiane są na zero logiczne wraz z resetemi wraz ze startemsystemu (wgrania strumienia konfiguracyjnego do układu FPGA).

 

4.2.4. Kontroler SPI

 
Kontroler SPI został zaczerpnięty z [10] i przedstawiony na rysunku 4.8. Zawiera gotowy moduł kontrolera SPI "SPI_W" [44] z biblioteki Altium Designer.
 

Rysunek 4.8. Kontroler SPI
 
Do kontrolera SPI podłączono 3 układy scalone (MAX9452, AD9512 oraz AD9777). Wybór aktywnego urządzenia realizowany jest na podstawie sygnałów SPI_MODE i SPI_CS za pośrednictwem multipleksera zgodnie z tab. 4.9.
 

Tabela 4.9. Tablica prawdy multipleksera [10]
 
Transmisja danych polega na wykonaniu 5 kroków:
  1. Wyzerowaniu rejestru CSR,
  2. Wpisaniu 0xFFh do rejestru CDIV,
  3. Wpisaniu do rejestru CSR:
    - 0x06h w celu komunikacji z AD9777,
    - 0x04h w celu komunikacji z AD9512,
    - 0x02h w celu komunikacji z MAX9452,
  4. Wykonaniu jednej z dwóch możliwości:
    - W przypadku nadawania: na wpisaniu bajtu do rejestru DATAOUT - bajt ten zostanie wysłany,
    - W przypadku odbioru: na wysłaniu dowolnego bajtu, powodując wytworzenie sygnału taktującego urządzenie docelowe. Bajt ten zostanie zignorowany przez urządzenie docelowe. Jeżeli urządzenie docelowe było przygotowane na nadawanie, to odebrany bajt należy odczytać z rejestru DATAIN. Jeżeli wymagane jest zapisanie/odczytanie większej ilości bajtów, to krok 4 należy powtarzać
  5. Wyzerowaniu rejestru CSR

 

4.2.5. Dzielnik Zegarów CLK_DIV

 
Blok dzielnika zegarów został zaczerpnięty z [10] i został przedstawiony na rysunku 4.9.
 

Rysunek 4.9. Schemat bloku CLK_DIV
 
Głównym elementem tego bloku są 32-bitowe rejestry konfiguracyjne widziane od adresu 0x7004h do 0x7007h. Wartości rejestrów spod adresów 0x7005h i 0x7007h konfigurują dzielniki kolejno zegara wejściowego do układu MAX9452 oraz zegara wejściowego układu AD9512. Dzielenie częstotliwości opisuje zależność:

4.2.6. Blok CLK_DISTR_REG

 
Blok CLK_DISTR_REG, prezentowany na rysunku 4.10, został zaczerpnięty z [10]. Blok odpowiada za sterowanie równoległym interfejsem układów dystrybucji zegara (układów MAX9452 i AD9512).
 

Rysunek 4.10. Blok CLK_DISTR_REG
 
Układ składa się z pojedynczego 32-bitowego rejestru widzianego pod adresem 0x7009h. Sterowanymi liniami, zgodnie z powyższym rysunkiem, są "FUNC" i "STAT" układu AD9512, oraz linie "CMON", "SEL0", "SEL1", "LOCK" i "INT" układu MAX9452. Znaczenia wartości logicznych na tych liniach zostały opisane w dokumentacji układów scalonych (MAX9452 w [33], AD9512 w [32]).
 

4.3. Zestaw modułów po stronie DIC

 
Zestaw modułów składa się z 7 części:
  1. "Przekładni" (SLAVE_PCI_PLUG), identycznej jak w przypadku płyty DAC,
  2. Dekodera adresów Wishbone-Interconnect,
  3. Kontrolera GPIB, podłączonego do Wishbone-Interconnect poprzez moduł podłączający 32-bitową szynę danych do szyny 8-bitowej,
  4. Kontrolera UART, podłączonego do Wishbone-Interconnect poprzez moduł podłączający 32-bitową szynę danych do szyny 8-bitowej,
  5. Kontrolera I2C, podłączonego doWishbone-Interconnect poprzezmoduł podłączający 32-bitową szynę danych do szyny 8-bitowej,
  6. Rejestru sterującego diodami na karcie DIC,
  7. Rejestru tylko-do-odczytu DIC_ID_REG, zawierającego kod identyfikacji 0x00444943h (3 młodsze bajty posiadają interpretację w kodzie ASCII: "DAC").
Zestaw modułów zamieszczono na rysunku 4.11.
 

Rysunek 4.11. Zestaw modułów po stronie DIC
 

4.3.1. Kontroler GPIB

 
Kontroler GPIB został zaadoptowany z [11]. Zmodyfikowaną wersję zamieszczono na rysunku 4.12 w formie blokowej.
 

Rysunek 4.12. Schemat blokowy kontrolera GPIB [11]
 
Dokonano następujących modyfikacji:
  1. Została dodana możliwość sprawdzania fiag "empty" oraz "full" kolejek fifo. Ich stan jest odczytywany spod adresu 0x8001h kontrolera według tabeli podanej poniżej:
 

Tabela 4.10. Odczyt stanów fiag kolejek fifo: 0x8001h
 
  1. Została dodana możliwość ustalania adresu kontrolera, wymaganego w protokole GPIB, poprzez równoległe linie CONN_ADD[7..0]. Adres ustawiany jest przez 5 najmłodszych bitów (starsze 3 są ignorowane). Zakres adresu jaki można ustalić przewiduje sam protokół i mieści się on pomiędzy 0x00h, a 0x1Eh. Jeżeli zostanie podany adres 0x1Fh, to adresem kontrolera będzie jednocześnie instrukcja rozadresowania wszystkich urządzeń - do czego nie można dopuścić.
  2. Została wprowadzona zmiana przejść oraz zredukowana liczba stanów (o jeden) automatu "state_machine_r" kontrolera:
    - zredukowano stan "NADRSD" (mnemonik z ang. od "Not adressed"),
    - zmieniono warunek przejścia ze stanu "IDLEr" do stanu "RDY2RCV" na:
    ATN_I_reg fi [(SPE_flag fi ADR2LST_flag) fi (!wbrfifo_full_i)]   .
Modyfikacje te spowodowały:
  • poprawne (nie przypadkowe) działanie automatu w przypadku chęci odczytu stanu linii "SRQ" (komenda "TST_SRQ"),
  • automat nie przechodzi do odbierania danych w przypadku, gdy kolejka odbioru jest zapełniona, co powoduje że dane nie są nadpisywane i może zostać odebrana duża (ponad rozmiar kolejki odbioru) ilość danych z urządzenia docelowego.

W celu używania tego modułu został on odpowiednio skonfigurowany. Parametry konfiguracyjne, użyte wartości oraz krótki opis ustawień znajdują się w tabeli 4.11 poniżej.
 

Tabela 4.11. Konfiguracja kontrolera GPIB
 
Kontroler steruje liniami interfejsu za pośrednictwem zapisu/odczytu bajtów pod/z adres/u 0x8000h:
  • zapis/odczyt wartości z przedziału 0x00h : 0x7Fh kontroluje szynę DIO (odpowiednio zapis – nadawanie, odczyt – odbieranie),
  • zapis 0x81 wprowadza stan linii IFC w aktywny, co resetuje również kolejki odbioru i zapisu,
  • zapis 0x82 wprowadza stan linii ATN w aktywny (przesyłanie komend),
  • zapis 0x83 wprowadza stan linii ATN w nieaktywny (przesyłanie danych),
  • zapis 0x84 wprowadza stan linii EOI w aktywny,
  • zapis 0x85 wywołuje sprawdzanie linii SRQ (wynik sprawdzenia jest umieszczany w kolejce odbioru w postaci 0xFFh, gdy SRQ jest aktywne, w przeciwnym wypadku 0x00h).

4.3.2. Kontroler RS232C

 
Do realizacji zadań interfejsu RS232 wykorzystano gotowy moduł "WB_UART" [45] z biblioteki Altium Designer.
 
Do transmisji zostały wykorzystane linie RxD i TxD, a nie wykorzystywana (w samej transmisji) linia RTS służy do sterowania multiplekserem. Zadaniem multipleksera jest, tylko w przypadku wysyłania danych, odłączenie linii TxD od portu TX1 na czas 8 wysyłanych pierwszych bajtów, które mają wartość przypadkową. Bajty te biorą się z faktu, iż przy początku transmisji kolejka fifo modułu "WB_UART" jest opróżniana.
 
W celu wykorzystania tego modułu należy go odpowiednio skonfigurować. Konfiguracja ta polega na dwóch czynnościach:
• zapisu odpowiednich liczb, zgodnie ze wzorem prezentowanym poniżej, do 3 rejestrów BRG, odpowiadających za generowanie baudrate:
 
 
Po konfiguracji moduł jest gotowy do nadawania i odbioru. Nadawanie polega na wpisaniu bajtu do rejestru SBUF, po ówczesnym sprawdzeniu fiagi "txfull", a odebranie bajtu na odczycie rejestru SBUF, po ówczesnym sprawdzeniu fiagi "rxempty". Flagi "txfull" oraz "rxempty" znajdują się w rejestrze STATUS.
 

4.3.3. Kontroler I2C

 
Do realizacji zadań interfejsu I2C użyto komponentu "I2C controller core" [46]. Kontroler ten został podłączony zgodnie z jego dokumentacją, z tą różnicą, iż na karcie DIC wyjścia tego kontrolera sterują odwracającymi buforami typu otwarty dren, stąd inwertery na jego wyjściach.

W celu wykorzystania modułu należy go odpowiednio skonfigurować. W tym celu należy najpierw wyzerować rejestr CTR, a następnie wprowadzić do rejestrów PRERlo i PRERhi wartości preskalera częstotliwości według podanego poniżej wzoru:

 
Obliczoną wartość należy zamienić na reprezentację szesnastkową i wprowadzić do rejestrów - starszy bajt do rejestru PRERhi, a młodszy do PRERlo. Następnie należy ustawić bit EN w rejestrze CTR. Działanie kontrolera prezentowane jest w postaci algorytmu blokowego na rysunku 4.13. Na rysunku wykorzystano oznaczenia wykorzystywane w dokumentacji tego modułu [46].
 

Rysunek 4.13. Algorytm blokowy kontrolera I2C
 
Wysyłanie danych polega na wpisaniu 7-bitowego adresu docelowego adresu,do rejestru TXR na pozycje 7 starszych bitów. Przy zapisie najmłodszy bit musi być wyzerowany. Następnie należy ustawić bity STA oraz WR w rejestrze komend, po czym należy sprawdzać fiagę TIP. Jeśli fiaga TIP przez długi czas jest ustawiona użytkownik musi zadecydować czy dalej czekać czy przerwać transmisję. Jeśli fiaga TIP jest zdjęta, to należy sprawdzić czy urządzenia docelowe potwierdziło odbiór. Jeśli zaistniał brak potwierdzenia adresu, to znaczy że urządzenie docelowe o takim adresie nie jest podłączone do magistrali I2C.

Kolejnym krokiem jest wpisanie pierwszego bajtu danych do rejestru TXR i ustawienie bitu WR. Po każdym wysłaniu sprawdzana jest fiaga TIP. Jeśli fiaga TIP jest przez długi czas ustawiona użytkownik musi podjąć decyzję czy czekać dłużej czy przerwać transmisję. Jeśli fiaga TIP jest zdjęta, to kontroler zakończył przesyłanie bajtu.

Następnie sprawdzane jest potwierdzenie odbioru. W tym przypadku brak potwierdzenie odbioru może oznaczać, że urządzenie docelowe odebrało ostatni bajt i samo kończy transmisję, ale bajt został przesłany poprawnie. Przed wysłaniem ostatniej danej należy ustawić bity STO oraz WR na, co kończy transmisję.

Sposób odczytywania danych jest podobny i wymaga wpisania 7 bitowego adresu na pozycje starsze pozycje rejestru TXR oraz ustawienia ’1’ na najmłodszym bicie.

Następnie ustawiane są bity STA i WR w rejestrze rozkazów. Podobnie jak w przypadku zapisu, należy sprawdzić potwierdzenie odbioru adresu. Jeśli odbiera się tylko jeden bajt, należy ustawić STO, RD oraz NACK (ACK=1) w rejestrze komend, w przeciwnym wypadku, bity STO oraz NACK należy ustalić przed ostatnim przesłaniem. Po każdym ustawieniu RD i sprawdzeniu fiagi TIP odebrany bajt jest dostępny w rejestrze RXR. Po ustawieniu RD i NACK przez kontroler urządzenie docelowe przesyła ostani bajt i zwalnia magistralę I2C.

 

4.3.4. Diody Led

 
Obsługę diod LED zaimplementowano w celach testowych. Ułatwiają one wykrywanie ewentualnych usterek przy uruchamianiu nowych modułów. Diody sterowane są przy pomocy rejestru 8-bitowego i mogą być używane jako prosty wskaźnik stanów logicznych.

 

------------------------

  1. Łukasz Dymanowski. Projekt i wykonanie modułu akwizycji danych z wykorzystaniem standardu PMC. Politechnika Warszawska, 2007.
  2. Kamil Lewandowski. Projekt i wykonanie karty PMC z interfejsami komunikacyjnymi. Politechnika Warszawska, 2007.
  1. Analog Devices. AD9512 Datasheet. http://www.analog.com/UploadedFiles/Data_Sheets/AD9512.pdf, Czerwiec 2005.
  2. Maxim. MAX9450-MAX9452 Datasheet. http://datasheets.maxim-ic.com/en/ds/MAX9450-MAX9452.pdf.
  1. John Clayton. RS232 system controller. http://www.opencores.org/project,rs232_syscon, 2005.
  2. FTDI Chip. FT245BM USB FIFO ( USB - Parallel ) I.C. http://www.ftdichip.com/Documents/DataSheets/DS_FT245BM.pdf.
  3. Altium. CR0150 WB_INTERCON Configurable Wishbone Interconnect. http://www2.altium.com/files/AltiumDesigner6/LearningGuides/CR0150%20WB_INTERCON%20Configurable%20Wishbone%20Interconnect.pdf.
  4. Altium. CR0152 WB_MEM_CTRL Configurable Wishbone Memory Controller. http://www.altium.com/files/altiumdesigner/s08/learningguides/CR0152%20WB_MEM_CTRL%20Configurable%20Wishbone%20Memory%20Controller.pdf.
  5. Altium. CR0118 FPGA Generic Library Guide. http://www.altium.com/files/altiumdesigner/s08/learningguides/CR0118%20FPGA%20Generic%20Library%20Guide.pdf.
  6. Altium. CR0153 SPI_W Serial Peripheral Interface Controller. http://www.altium.com/files/altiumdesigner/s08/learningguides/CR0153%20SPI_W%20Serial%20Peripheral%20Interface%20Controller.pdf.
  7. Altium. CR0157 WB_UART8 Serial Communications Port. http://www.altium.com/files/altiumdesigner/s08/learningguides/CR0157%20WB_UART8%20Serial%20Communications%20Port.pdf.
  8. Richard Herveille. I2C-Master Core Specification. http://www.opencores.org/project,i2c, Lipiec 2003.