Zadanie 1: Dzielnik¶
Data ogłoszenia: 27.10.2020
Termin oddania: 24.11.2020
Szablon rozwiązania i testy: divider_template.py
Napisać moduł dzielący dwie liczby bez znaku przez siebie.
Moduł powinien mieć:
parametr
widthokreślający szerokość wejść i wyjść w bitachwejście
a,width-bitowe bez znaku: dzielnawejście
b,width-bitowe bez znaku: dzielnikwejście
start, 1-bitowe: sygnał startu. Gdy to wejście będzie równe 1, dzielnik powinien rozpocząć dzielenie.wyjście
busy, 1-bitowe: powinno być ustawione na 1 gdy dzielnik jest zajęty, zaczynając od cyklu po ustawieniustart, a kończąc gdy wynik jest gotowy.wyjście
q,width-bitowe: wynik dzielenia (a / b)wyjście
r,width-bitowe: reszta z dzielenia (a % b)wyjście
err, 1-bitowe: ustawione jeśli wystąpił błąd dzielenia (bjest równe 0);qirmogą mieć w takim wypadku dowolną wartość
Protokół użycia dzielnika jest następujący:
Po resecie, dzielnik nic nie robi (
busyjest równe 0).Dopóki
startjest równe 0, dzielnik nic nie robi (nie zmienia stanu wyjść, itp).Gdy
busyjest równe 0, użytkownikowi wolno rozpocząć operację dzielenia przez ustawienie wejśćaiboraz ustawieniestartna 1. Dzielnik rozpocznie dzielenie w następnym cyklu zegara. Od następnego cyklu dzielnik ustawi teżbusyna 1 (chyba, że będzie w stanie dać wynik w jednym cyklu zegara).Dopóki dzielnik liczy,
busyjest ustawione na 1, a użytkownikowi nie wolno ustawićstartna 1. Stan wyjść może się dowolnie zmieniać w tym czasie.Gdy dzielnik policzy wynik, ustawia
busyna 0. W tym samym cyklu ustawia równieżerr,qirna wyliczony wynik (nie musi ustawiaćqirjeśli nastąpił błąd).
Dzielenie jest skomplikowaną operacją — nie należy próbować zrobić dzielnika działającego w jednym cyklu (z wyjątkiem szczególnych przypadków, jak np. wykrywanie błędów), gdyż spowoduje to po prostu zbyt długą ścieżkę krytyczną w realizacji sprzętowej i będzie bardzo ograniczało maksymalną częstotliwość zegara.
Istnieje wiele ciekawych algorytmów dzielenia do realizacji sprzętowej. Na potrzeby tego zadania wystarczy użyć prostego algorytmu liczącego jeden bit wyniku na cykl:
r = a;
q = 0;
for (pos = width-1; pos >= 0; pos--) {
bool bit = (r >= (b << pos));
if (bit)
r -= b << pos;
q = q << 1 | bit;
}