wtorek, 28 czerwca 2016

[11] STM32F4 - sprzętowy kooprocesor arytmetyczny FPU

Ten post chciałbym poświęcić kooprocesorowi arytmetycznemu FPU.

FPU - Opis


FPU czyli arytmetic logic unit jest to wyspecjalizowany blok sprzętowy, którego zadaniem jest przyśpieszenie obliczeń zmiennoprzecinkowych. 

Operacje na liczbach zmiennoprzecinkowych w przypadku nie wykorzystywania FPU są bardzo czasochłonne, powodem tego jest dekodowanie operandów oraz modyfikowanie wartości w celu uzyskania takich samych wykładników. Po jednokrotnej operacji są one ponownie kodowane, po czym proces zaczyna się od początku.


W przypadku kooprocesora FPU wszystkie operacje są wykonywane przez część hardwaru zintegrowaną w procesorze, przez co unika się wykonywania działań poprzez kompilator. 

Ma on bardzo duże znaczenie przy projektach które mają za zadanie wykonać dużo obliczeń np przy przetwarzaniu sygnałów DSP, obróbce grafiki czy różnego rodzaju filtrach cyfrowych (np. Kalmana, Alfa - Beta)

Reprezentacja liczb zmiennoprzecinkowych


W celu zapisania takiej liczby wykorzystuje się znak (the sign), wykładnik(the exponent) oraz mantyse (the mantissa). Cała specyfikacja sposobu reprezentacji tych danych została opisana w specyfikacji IEEE 754.

Rys. 1. Reprezentacja liczby zmiennoprzecinkowej [wikipedia]

W zależności od rodzaju języka programowania i typu wartości liczba zmiennoprzecinkowa może być zdefiniowana na 16, 32(float w C), 48, 64(double w C) oraz 80 bitach.

Bit 31 odpowiada za znak czyli dodatni bądź ujemny (jeśli jeden to minus). Następnie jest wykładnik, który odpowiada za reprezentacje części całkowitej, ostatnim elementem jest mantysa, pozwala ona na przedstawienie części ułamkowej.

Przedstawiony na rysunku 1 format odpowiada za tryb pojedynczej precyzji, w jego skład wchodzi jeden bit znaku, 8 bitów wykładnika oraz 23 bity mantysy. Dla trybu podwójnej precyzji, który jest obsługiwany przez FPU np. w STM32F7, będą to 64 bity podzielony w taki sposób, że dla znaku będzie przeznaczony 1 bit, wykładnik 11 bitów, natomiast mantysa aż 52 bity.

FPU w STM32F4


W mikrokontrolerze został zintegrowany układ o pojedynczej precyzji, który komunikacje z nim wykonuje przy użyciu rejestru z 32 rejestrami pojedynczej precyzji zintegrowanymi w układzie. Możliwa jest także zmiana sposobu jego działania, co spowoduje uzyskaniem 16 rejestrów zawierających 64 bity o podwójnej precyzji.

Rejestry


Wszystkie rejestry dostępne dla FPU są typu read/write, każdy z nich jest 32 bitowy:

CPACR - (Coprocessor access control register)
FPCCR - (Floating point context control register)
FPCAR - (Floating point context address register)
FPDSCR - (Floating point status control register)
FPSCR - (Status and control register)

Główne ustawienia prowadzone są w rejestrze FPSCR, w którym istnieje możliwość ustawiania takich elemtów jak: ustawienie trybów pracy, konfiguracja pracy, tryb zaokrąglania liczby, zawiera takie flagi jak znak minus, zero, przeniesienie czy pożyczka. Możliwe jest także ustawianie znacznika błędów np. ustawiony tryb zaokrąglania czy dzielenia przez zero, które są obsługiwane przez system przerwań.

CPACR natomiast pozwana na aktywacje kooprocesora, oraz na ustalenie poziomu dostępu do niego. Można wybrać tryb zablokowany, pełny bądź ograniczony. Należy to odpowiednio dobrać ponieważ domyślnie FPU jest wyłączony.

Poniżej przedstawię, krótki opis poszczególnych rejestrów:

FPSCR:

Rejestr ten przechowuje informacje odnośnie statusu operacji, wystawionych flag czy konfiguracji FPU. Czyli zawiera wszystkie konieczne 

Rys. 2. Rejestr FPSCR

Bity 31, 30, 29, 28 są ustawianie po operacji porównania liczb, bądź dokonania operacji.
26,25,24,23 i 22 pozwalają na ustawienie alternatywnych trybów pracy(AHP, DN, FZ) oraz trybu zaookrąglania (RM).

Występuje 6 rodzajów flag zapisanych na bitach 7 oraz od 4 do 0. Zawierają one następujące opcje:

Flush to zero - IDC
Inexact result - IXC - niedokładny wynik
Underflow - UFC - niedomiar, liczba nieznormalizowana
Overflow - OFC - przepełnienie
Division by zero - DZC - dzielenie przez zero
Invalid operaction - IOC - nie poprawna operacja

Flagi IDC, UFC, OFC, DZC, IOC zostały podłączone do kontrolera przerwań, natomiast flaga IXC musi być obdługiwana w programie poprzez odpowiednie ustawianie wartości.

CPACR:

Rejestr ten pozwala na ustawienie sposobu dostępu do FPU za pomocą bitów 23 do 20. Poniżej przedstawiam dostępne konfiguracje:

  • 0b00 - Dostęp zabroniony
  • 0b01 - Dostęp uprzywilejowany
  • 0b10 - Dostęp zarezerwowany. W tym przypadku nie można przewidzieć sposobu uzyskania dostępu do danych.
  • 0b11 - Dostęp pełny

Rys. 3. Rejestr CPACR

FPCCR:

Do tego rejestru wprowadzane lub odczytywane są dane kontrolne.

Rys. 4. Rejestr FPCCR

FPCAR:

Zawierają dane dotyczące adresu rejestru.

Rys. 5. Rejestr FPCAR

FPDSCR:

Przechowuje domyślne wartości rejestrów z danymi kontrolnymi.

Rys. 6. Rejestr FPDSCR

Wyjątki


Jak już wspomniałem wcześniej występują pewnego rodzaju wyjątki, znaczniki błędów, jakie są obsługiwane przez system przerwań w rejestrze FPSCR. Można wyróżnić następujące operacje: 


  • Błędne działanie, wynik NaN (Not a Number) np. 0/0
  • Dzielenie przez zero
  • Flush to zero. Włączenie po ustawieniu bitu 24 w rejestrze FPSCR.
  • Otrzymana liczba znajduje się poza zdefiniowanym formatem. Występuje przepełnienie lub niedopełnienie.
  • Niedokładny wynik. Nie generuje przerwania, musi on zostać obsłużony programowo.

Włączenie FPU można wykonać bezpośrednio w programie Keil qVision. Sposób włączenia przedstawiono na rysunku zdefiniowanym poniżej:

Rys. 7. Włączenie FPU

Jak można zaobserwować na rysunku FPU w STM32F4 wspiera obliczenia pojedynczej precyzji czyli float, typ double nie jest wspierany w tym mikrokontrolerze.

Bibliografia

[1] Floating point unit demonstatrion on STM32 microcontrollers DM00047230.pdf