feat: add lab-rv32i-c-machine-timer card
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
# 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ą high–low–high, również przez rollover;
|
||||
2. jednorazowe przerwanie machine timer z `mtimecmp`, `mie.MTIE`,
|
||||
`mstatus.MIE`, wektorem 7 i powrotem `mret`;
|
||||
3. okresowe deadline’y `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), deadline’y 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 fixture’em 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 A1–A8. Widok A3 jest N/D tylko
|
||||
w Task01; w Task02 i Task03 dowodem dispatchu jest faktyczny wybór slotu
|
||||
`mtvec` na podstawie przyczyny przerwania.
|
||||
Reference in New Issue
Block a user