APB adresni prostor periferija
Hazard3-Doom izlaže sporije SoC periferije preko 32-bitnog APB sabirničkog
prostora iza Hazard3 AHB-L sistemske sabirnice. CPU load/store pristupi u
području 0x40000000 prolaze kroz AHB-u-APB most, a zatim ih dekodira APB
splitter u third_party/Hazard3/example_soc/soc/example_soc.v.
Adrese na ovoj stranici pripadaju Hazard3-Doom SoC integraciji. One nisu arhitekturne RISC-V adrese i nisu fiksirane samim Hazard3 CPU-om.
APB prozori dekodera
Trenutačni APB splitter izlaže šest slave blokova:
Periferija |
CPU baza |
Prozor dekodera |
RTL / softversko sučelje |
|---|---|---|---|
RISC-V timer |
|
|
|
UART |
|
|
|
GPIO |
|
|
|
SAO I2C/GPIO |
|
|
|
micro-SD SPI |
|
|
|
HDMI/video |
|
|
|
Prozori dekodera veći su od stvarno implementiranih skupova registara. Adresa unutar dekodiranog prozora ne znači da na toj adresi postoji registar. Softver treba koristiti samo dokumentirane offsete u nastavku.
Raspon 0x4000B000-0x4000BFFF trenutačno nije dodijeljen nijednoj APB
periferiji.
Zajednički MMIO pristup
Samostalni primjeri koriste jednostavan volatile 32-bitni pristup:
#include <stdint.h>
#define MMIO32(address) \
(*(volatile uint32_t *)(uintptr_t)(address))
Zajedničke definicije primjera nalaze se u
examples/common/hazard3_apb.h. Jedan zajednički header smanjuje mogućnost da
se pojedini primjeri odvoje od stvarne RTL mape.
RISC-V timer - 0x40000000
Timer implementira 64-bitni mtime brojač i 64-bitni mtimecmp komparator
preko 32-bitnog APB-a. Hazard3-Doom mu daje tick od jedne mikrosekunde, pa
mtime broji mikrosekunde dok hart radi. Brojač se zaustavlja dok je hart
zaustavljen debuggerom.
Offset |
Adresa |
Registar |
Opis |
|---|---|---|---|
|
|
|
Bit 0 uključuje timer. Nakon reseta je uključen. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Za koherentno 64-bitno čitanje provjerite da se gornja riječ nije promijenila oko čitanja donje riječi:
static uint64_t timer_read_us(void)
{
uint32_t hi1;
uint32_t lo;
uint32_t hi2;
do {
hi1 = MMIO32(0x4000000cu);
lo = MMIO32(0x40000008u);
hi2 = MMIO32(0x4000000cu);
} while (hi1 != hi2);
return ((uint64_t)hi1 << 32) | lo;
}
Pri izmjeni mtimecmp najprije upišite 0xFFFFFFFF u gornju riječ ako bi
privremeno compare podudaranje bilo problematično, zatim donju riječ i na kraju
konačnu gornju riječ.
UART - 0x40004000
UART je Hazard3-libfpga uart_mini periferija. Sadrži male TX/RX FIFO-e,
frakcijski djelitelj, opcionalne prekide, CTS i loopback.
Offset |
Adresa |
Registar |
Važna polja |
|---|---|---|---|
|
|
|
bit 0 EN, bit 1 BUSY, bit 2 TXIE, bit 3 RXIE, bit 4 CTSEN, bit 8 LOOPBACK. |
|
|
|
bitovi 13:4 cijeli dio, bitovi 3:0 frakcijski dio djelitelja. |
|
|
|
TX/RX nivo, full/empty i sticky error status. |
|
|
|
Upis bitova 7:0 dodaje jedan bajt u TX FIFO. |
|
|
|
Čitanje bitova 7:0 vraća i uklanja jedan bajt iz RX FIFO-a. |
FSTAT polja su:
7:0 TXLEVEL
8 TXFULL
9 TXEMPTY
10 TXOVER sticky, upis 1 briše
11 TXUNDER sticky, upis 1 briše
23:16 RXLEVEL
24 RXFULL
25 RXEMPTY
26 RXOVER sticky, upis 1 briše
27 RXUNDER sticky, upis 1 briše
Uz normalni 8x oversampling, djelitelj je fixed-point vrijednost s četiri frakcijska bita:
baud ~= sys_clk / (8 * DIV)
DIV_register = round((sys_clk * 16) / (baud * 8))
Trenutačno generirani uart_regs.v pri čitanju DIV vraća reset vrijednost,
a ne programirani djelitelj. Softver zato ne treba koristiti DIV readback
za provjeru baud-rate upisa.
Minimalni blokirajući TX:
#define UART_FSTAT MMIO32(0x40004008u)
#define UART_TX MMIO32(0x4000400cu)
#define UART_TXFULL (1u << 8)
static void uart_putc(char c)
{
while ((UART_FSTAT & UART_TXFULL) != 0u) {
}
UART_TX = (uint8_t)c;
}
GPIO - 0x40008000
GPIO blok trenutačno ima jedan 8-bitni izlazni registar.
Offset |
Adresa |
Registar |
Opis |
|---|---|---|---|
|
|
|
Bitovi 7:0 upravljaju |
Zadržava se samo donji bajt upisa:
MMIO32(0x40008000u) = 0x55u;
Wrapper pločice određuje što pojedini gpio_out bit stvarno upravlja na
danoj FPGA ciljnoj pločici.
SAO I2C/GPIO - 0x40009000
SAO periferija kombinira softverski upravljani I2C engine, dva SAO GPIO-a, sirovi status linija, identifikacijske registre te status ESP32/Hazard3 vlasništva.
Offset |
Adresa |
Registar |
Opis |
|---|---|---|---|
|
|
|
Upis niskorazinske I2C naredbe. |
|
|
|
I2C rezultat, linije, GPIO i status vlasništva. |
|
|
|
Bajt za WRITE naredbu. |
|
|
|
Zadnji primljeni bajt. |
|
|
|
16-bitni I2C timing djelitelj. |
|
|
|
Clock-stretch timeout u ciklusima sistemskog takta. |
|
|
|
SAO GPIO izlaz/OE i sinkronizirano stanje ulaza. |
|
|
|
Sirovo sinkronizirano stanje SDA, SCL, GPIO1 i GPIO2. |
|
|
|
|
|
|
|
Trenutačna verzija |
|
|
|
bit 0 ESP owner, bit 1 ESP request. |
Vrijednosti COMMAND:
1 START
2 STOP
3 WRITE
4 READ_ACK
5 READ_NACK
6 RECOVER
7 ABORT
Bitovi STATUS:
0 BUSY
1 DONE
2 ACK
3 NACK
4 TIMEOUT
5 REJECTED
6 BUS_ACTIVE
7 SDA
8 SCL
9 GPIO1
10 GPIO2
11 RECOVERED
12 ESP_OWNER
13 ESP_REQUEST
DONE, TIMEOUT, REJECTED i RECOVERED su sticky. Upis jedinice u
odgovarajući STATUS bit briše taj sticky status.
Reset I2C djelitelj odabire se iz sistemskog takta za približno 100 kHz, a reset clock-stretch timeout je 10 ms.
micro-SD SPI - 0x4000A000
micro-SD periferija je mali softverski upravljani SPI mode-0 master, MSB first, namjerno bez FIFO-a i DMA-a.
Offset |
Adresa |
Registar |
Opis |
|---|---|---|---|
|
|
|
bit 0 je |
|
|
|
16-bitni djelitelj poluperiode SPI takta. |
|
|
|
Upis donjeg bajta pokreće transfer; čitanje vraća primljeni bajt. |
|
|
|
bit 0 BUSY. |
SPI takt je:
SCLK = sys_clk / (2 * (CLKDIV + 1))
Na 50 MHz reset vrijednost 124 daje 200 kHz za inicijalizaciju. APB prozor
postoji i kada je SD_SPI_ENABLE false; tada onemogućena integracija vraća
nule i ostavlja SD izlaze neaktivnima.
Transfer jednog bajta:
static uint8_t sd_spi_xfer(uint8_t tx)
{
while ((MMIO32(0x4000a00cu) & 1u) != 0u) {
}
MMIO32(0x4000a008u) = tx;
while ((MMIO32(0x4000a00cu) & 1u) != 0u) {
}
return (uint8_t)MMIO32(0x4000a008u);
}
Ne pokrećite proizvoljne transfere dok druga softverska komponenta koristi karticu ili tijekom provjere zajedničkog ULX3S ESP32/FPGA SD vlasništva.
HDMI/video - 0x4000C000
Video APB blok upravlja HDMI/video putem i izvještava njegovo stanje. Framebuffer pikseli nisu u ovom APB prozoru; framebufferi se nalaze u video rezervaciji vanjske memorije opisanoj u Memorijska mapa.
Offset |
Adresa |
Registar |
Opis |
|---|---|---|---|
|
|
|
Video mode, framebuffer, DMA i capability status. |
|
|
|
Indexed/buffer/present/direct/resolution kontrola. |
|
|
|
Odabir palette unosa. |
|
|
|
Podatak palette. |
|
|
|
Brojač frameova. |
|
|
|
Dijagnostički DMA cycle brojač. |
|
|
|
Broj dovršenih present operacija. |
|
|
|
Identifikator pločice/FPGA builda. |
|
|
|
Status kontrolera/adaptera vanjske memorije. |
|
|
|
Identifikator jezgre vanjske memorije. |
|
|
|
Identifikator Hazard3 memorijskog adaptera. |
|
|
|
Adresa/kontrola izravnog video upisa. |
|
|
|
Podatak izravnog video upisa. |
Važni STATUS bitovi:
0 FRONT_BUFFER
1 PRESENT_PENDING
2 INDEXED
3 VBLANK
4 SDRAM_READY
5 FRAME_VALID
6 INTERNAL_BUFFER
7 DMA_BUSY
8 SWAP_PENDING
9 DIRECT_SUPPORTED
10 DIRECT_WRITE_BUSY
11 HIGH_RES_SUPPORTED
12 HIGH_RES_ACTIVE
13 GUI_RES_SUPPORTED
14 GUI_RES_ACTIVE
CONTROL trenutačno koristi:
0 INDEXED
1 BUFFER1
2 PRESENT
3 DIRECT
4 HIGH_RES
5 GUI_RES
doom/hazard3_video.h je izvor istine za softverski vidljive video bitove i
povezani raspored framebuffer memorije.
Samostalni APB primjeri
U examples/ su dodana dva bare-metal primjera. Ne linkaju se s rezidentnim
monitorom niti s Doomom.
examples/apb-register-dumpInicijalizira UART i ispisuje nedestruktivni snapshot svih šest APB periferija. Ne pokreće SAO ili SD transakcije, ne mijenja GPIO izlaze i ne mijenja video stanje.
examples/apb-uart-timerAktivno demonstrira timer i UART. Uključuje timer, čita
mtime, čeka milijun mikrosekundnih tickova, ispisuje proteklo vrijeme i zatim radi UART echo sve dok ne primiqiliQ.
Oba primjera dijele definicije registara i minimalni startup u
examples/common/. Svaki se i dalje može izgraditi zasebno.
Izgradnja primjera
Iz Bash-a ili WSL-a u korijenu repozitorija:
make -C examples
Ili samo jedan primjer:
make -C examples/apb-register-dump
make -C examples/apb-uart-timer
Zadana izgradnja pretpostavlja Hazard3 sistemski takt 50 MHz i UART 115200 baud. Za cilj od 40 MHz, poput normalnih ULX4M-LD ili ULX3S 12F profila:
make -C examples SYS_CLK_HZ=40000000
Makefileovi slijede iste konvencije za toolchain kao glavni projekt. Prvo
postuju TOOLCHAIN_PREFIX, prihvacaju i CROSS_COMPILE, prepoznaju staru
lokaciju /opt/riscv/bin/riscv32-unknown-elf- te inace koriste
riscv-none-elf-* iz PATH. Uobicajeni puni instalacijski postupak stavlja
xPack kompajler u PATH. Lokalna instalacija pod bin/riscv-gcc ostaje kao
kompatibilni fallback. Windows .exe alati otkrivaju se automatski kada je
njihov put vidljiv iz Bash/WSL-a; EXEEXT=.exe moze se postaviti i rucno.
Svaki primjer proizvodi .elf, .bin, .map i .lst u svom
build/ direktoriju. Generirani output nije namijenjen commitiranju.
Pokretanje preko OpenOCD/GDB
Primjeri su linkani na 0x20100000, normalni početak Doom executable prozora.
Time ostaju izvan rezidentnog monitora i rade s 32 MiB i 64 MiB softverskim
memorijskim profilima.
Kontroler vanjske memorije mora već biti inicijaliziran. Najjednostavnije je pokrenuti normalni rezidentni monitor, potvrditi da je vanjska memorija spremna, pokrenuti normalnu Hazard3 OpenOCD sesiju i zatim spojiti GDB bez reseta FPGA-a ili harta.
Za apb-register-dump:
riscv-none-elf-gdb examples/apb-register-dump/build/apb-register-dump.elf
(gdb) target extended-remote :3333
(gdb) monitor halt
(gdb) load
(gdb) set $pc = _start
(gdb) continue
Za drugi ELF koristite isti postupak. Budući da primjer zamjenjuje normalni
izvršni sadržaj na 0x20100000, prije ponovnog pokretanja Dooma ponovno ga
učitajte.
Važno
Nemojte napraviti target reset neposredno prije učitavanja primjera. Reset može vratiti sustav u stanje prije inicijalizacije SDRAM/DDR memorije, dok se ovi ELF-ovi izvršavaju upravo iz vanjske memorije.
Izvorne datoteke koje su izvor istine
Kod promjene SoC-a provjerite ovu stranicu i
examples/common/hazard3_apb.h prema implementaciji:
third_party/Hazard3/example_soc/soc/example_soc.v- APB dekoder.third_party/Hazard3/example_soc/soc/peri/hazard3_riscv_timer.v- timer.third_party/Hazard3/example_soc/libfpga/peris/uart/uart_regs.v- UART registri.third_party/Hazard3/example_soc/soc/apb_gpio.v- GPIO.third_party/Hazard3/example_soc/soc/apb_sao_bridge.v- SAO.third_party/Hazard3/example_soc/soc/apb_sd_spi.v- SD SPI.doom/hazard3_video.h- softverski vidljive video definicije.