.. _z1-divider:

===================
Zadanie 1: Dzielnik
===================

Data ogłoszenia: 27.10.2020

Termin oddania: 24.11.2020

Szablon rozwiązania i testy: :download:`divider_template.py`

Napisać moduł dzielący dwie liczby bez znaku przez siebie.

Moduł powinien mieć:

- parametr ``width`` określający szerokość wejść i wyjść w bitach
- wejście ``a``, ``width``-bitowe bez znaku: dzielna
- wejście ``b``, ``width``-bitowe bez znaku: dzielnik
- wejś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 ustawieniu ``start``, 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 (``b`` jest równe 0); ``q`` i ``r`` mogą mieć w takim wypadku dowolną wartość

Protokół użycia dzielnika jest następujący:

1. Po resecie, dzielnik nic nie robi (``busy`` jest rĂłwne 0).
2. Dopóki ``start`` jest równe 0, dzielnik nic nie robi (nie zmienia stanu wyjść, itp).
3. Gdy ``busy`` jest równe 0, użytkownikowi wolno rozpocząć operację dzielenia przez ustawienie wejść ``a`` i ``b`` oraz ustawienie ``start`` na 1.  Dzielnik rozpocznie dzielenie w następnym cyklu zegara.  Od następnego cyklu dzielnik ustawi też ``busy`` na 1 (chyba, że będzie w stanie dać wynik w jednym cyklu zegara).
4. Dopóki dzielnik liczy, ``busy`` jest ustawione na 1, a użytkownikowi nie wolno ustawić ``start`` na 1.  Stan wyjść może się dowolnie zmieniać w tym czasie.
5. Gdy dzielnik policzy wynik, ustawia ``busy`` na 0.  W tym samym cyklu ustawia również ``err``, ``q`` i ``r`` na wyliczony wynik (nie musi ustawiać ``q`` i ``r`` jeś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;
    }