Files
lab-rv32i-c-machine-timer/README.md
T
2026-07-21 19:14:20 +02:00

66 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# C11 — machine timer na RV32I/Hazard3
Karta pokazuje trzy osobne, wykonywalne przykłady obsługi 64-bitowego timera
z 32-bitowego rdzenia:
1. spójny odczyt `mtime` sekwencją highlowhigh, również przez rollover;
2. jednorazowe przerwanie machine timer z `mtimecmp`, `mie.MTIE`,
`mstatus.MIE`, wektorem 7 i powrotem `mret`;
3. okresowe deadliney `deadline += period`, z zapisem czasu planowanego,
obserwowanego i spóźnienia każdego ticka.
To nie jest model hostowy. Programy są kompilowane jako freestanding
RV32I+Zicsr+Zifencei i wykonywane przez RTL Hazard3/Verilator. Testbench
inkrementuje `mtime` w każdym kroku oraz wystawia poziomowe żądanie timera,
gdy `mtime >= mtimecmp[hart]`.
## Budowanie i dowód wykonania
```sh
make tasks
./tests/test_hazard3.sh
```
Test zewnętrzny wymaga kodu wyjścia 0, braku nieobsłużonej pułapki i braku
timeoutu, a następnie sprawdza raportowane relacje. Przy bieżącym RTL uzyskano:
- Task01: wybrany offset `0x13`, 2 próby, poprawny high po rolloverze;
- Task02: dokładnie 1 ISR, `mcause=0x80000007`, pending 0 przed i po,
wznowienie po `wfi`;
- Task03: 4 ISR, okres `0x640` (1600), deadliney oddalone dokładnie o okres,
obserwowane spóźnienie `0x28` (40) dla każdego ticka.
Wartość 40 nie jest kontraktem architektury — zależy od RTL, magistrali,
prologu wygenerowanego przez kompilator i chwili próbkowania. Kontraktem karty
jest `observed >= scheduled`, poprawna arytmetyka spóźnienia i stały krok
deadline’ów.
## Granice i ważne rozróżnienia
- Zapis do `mtime` w Task01 jest wyłącznie fixtureem dostępnego testbencha;
kod produkcyjny nie powinien zakładać, że licznik czasu jest zapisywalny.
- `mtime` i `mtimecmp` są urządzeniami 64-bitowymi widzianymi przez cztery
rejestry 32-bitowe. Zwykłe C `uint64_t` nie daje atomowej transakcji MMIO.
- Źródłem zdarzenia jest porównanie `mtime >= mtimecmp`. Bity MTIE i MIE tylko
przepuszczają pending do rdzenia; nie tworzą zdarzenia i go nie kasują.
- Machine timer jest poziomowy. Handler przesuwa `mtimecmp`; samo wejście do
ISR ani odczyt `mcause` nie czyści źródła.
- `common/init.S` ustawia `mtvec` w tryb wektorowy. Slot 7 wybiera symbol
`isr_machine_timer`; atrybut GCC `interrupt("machine")` generuje `mret`.
- Model `deadline += period` zachowuje fazę. `now + period` użyte jako jedyna
reguła przenosi każde spóźnienie na kolejne wyzwolenie i powoduje dryf.
- Karta nie obejmuje jeszcze sterownika RP2350, ticka RTOS, współdzielenia
danych z wieloma hartami ani polityki nadrabiania wielu pominiętych okresów.
## Materiały karty
```sh
./scripts/render_card_layouts.sh
./scripts/render_new_pdf.sh
./tests/test_card.sh
```
Każdy z trzech przykładów ma dokładnie widoki A1A8. Widok A3 jest N/D tylko
w Task01; w Task02 i Task03 dowodem dispatchu jest faktyczny wybór slotu
`mtvec` na podstawie przyczyny przerwania.