Soft AVR core - újabb verzió

Egy kicsit intenzívebb fejlesztési szakasz és néhány korábban felmerült kérdés után kijött a korábban bemutatott, saját fejlesztésű AVR proci és/vagy SoC következő verziója. Javítva vagyon benne pár CPU core és perifériákat érintő bug, ami a tesztek során ugyan előjött, de jelenlegi felhasználásnál (azaz konkrét programok futtatásánál) nem jött elő, sem égen, sem földön.

Gyorsabbnak nem lett számottevően gyorsabb (a critical path még mindig ugyanaz :/), a betervezett 3-4-x lépéses instruction pipeline egy ettől független projekt keretein belül formálódik majd egy szép napon. Cserébe a bugfixeken felül lett egy adag új periféria, teljes clock cycle kompatibilitás, opcionális interrupt acknowledgement ha olyasmire van igény, watchdog egyszerűsítés és egy kis sleep mode + power saving támogatás desszertnek.

A teszteléshez nagyon jól jött hogy ez a core már mindenféle változtatás nélkül tudja futtatni a full preemtív multitaszkingra beállított FreeRTOS-t is: az a viszonylag intenzív adat- és megszakítás-terhelés amit az ad (~10000 óraciklusonkent context switch váltás, ~100 óraciklusonként UART megszakítás, mindkét irányban, stb) tényleg előhozott egy-két hibát. És ez a FreeRTOS szépen támogatja az operációs idle process/state-t is -- amiről tudjuk, hogyha nem jó a támogatása akkor gyorsan merül az akku a telefonocskánkban. Ezzel -- persze amellett hogy beágyazott cuccmányokban, vagy akkus-napelemes cuccokban, mint egy műhold, jobban tudunk gazdálkodni a teljesítménnyel --  a sleep CPU állapot összes aspektusa is jól kimérhető és/vagy szószerint láthatóvá tehető egyetlen darab Verilog assignment-tel (pl. minél nagyobb az operendszer terhelése, annál fényesebben világit a led). Meg persze multiméterrel vagy USB-s fogyasztásmérővel is. Mindez 3kLUT/LC-be, 8k-nyi kódba és 1k RAM-ba kényelmesen belesűrítve.
 

Hozzászólások

Ez tök jól néz ki, ha valaha AVR core-ra lesz szükségem.

Csak egy észrevétel: nem lehetne egy clock enable-t beletenni, ha netán egy nagyobb SoC projektbe kellene beleintegrálni? Így kaphatna egy általános rendszerórajelet, de a valós sebességet a CE adná. Hasznos lenne kiküszöbölni a különböző clock domainek keresztezéséből származó problémákat.

Köszi!

Csak egy észrevétel: nem lehetne egy clock enable-t beletenni, ha netán egy nagyobb SoC projektbe kellene beleintegrálni?

Olyat tervezek majd hogy a memoria-illeszteshez teszek egy *mem_valid jellegu, wait state allapotot kivalto inputot (mmint ami a CPU fele input). Vagyis, ez a dmem_* buszra (adatmemoria) keszen van, a pmem_*-ra (programmemoria meg nincs). Es akkor ezzel ki lehet valtani kivulrol is egy hasonlo alvo allapotot - oke, nehany esetben csak egy par oraciklussal kesobb, de . Csakhat igen, hulye Harvard-architektura, hogy minden ilyesmit 2x kell megcsinalni ;) Raadasul elegge kulonbozo ez a ket illesztes a gyakorlatban.

Ez is lehet hasznos, ha mondjuk nem BRAM-ból szolgálod ki a CPU-t, amire én gondolok, hogy pl. van egy VGA áramköröd, ami 25MHz-en megy, ehhez akarsz egy 10MHz-es AVR-t, ami rajzol rá, akkor ugyanarról az órajelről hajthatnád mind a kettőt. Persze, mondhatod, hogy legyen az AVR is 25MHz, és kész.

Egyébként nem olyan komplikált ez a CE, kb. annyi, hogy minden always (posedge clk)... blokkot egy if(CE) begin...end-el kell kezdeni és lezárni.

Aha, igen, erre tenyleg jo egy hasonlo CE bemenet, ha igy lassitanal le egy CPU-t. Annyi belso regisztere tenyleg nincs ennek, a critical path-ot meg nem noveli meg. 

Mondjuk ettol fuggetlenul egy VGA programozast inkabb ugy csinalnek egy effele rendszerben hogy egy DPRAM irasi oldala lenne bekepezve az AVR dram_* buszara mig a VGA driver a DPRAM olvasasi oldalat hajtja meg. Legalabbis ennel az iCE40HX csaladnal, amit hasznalok, az elemi cellak (SB_RAM40_4K) ket kulon orajellel rendelkeznek. Azaz itt a hardver maga megold(hat)ja a kulonbozo clock domain-eket - es ha epp nem kell video frissites, akkor a CPU meg onmagat teszi alvo allapotba (`sleep`-pel).

Nyilván ki lehet használni a DPRAM adta lehetőségeket, ha van belőle elég. De ez csak egy példa volt. Ha a framebuffered csak egy külső modulban fér el, akkor máris kell hozzá egy (S)DRAM vezérlő, amit már két különböző órajelű áramkör fog használni.

Más perifériák is lehetnek más-más órajel követelménnyel, pl. egy USB vezérlő 48MHz-el, vagy egy RMII 50MHz-el, SD kártya SPI módban 24 MHz-el, stb...

Ah, igen. Ha igen ennyire valtozatosak es/vagy kulonbozo igenyuek ezek a periferiak, akkor sztem hosszutavon nem usznank meg a clock domain-ek osszeilleszteset. Foleg hogy az sem feltetlen opcio hogy mondjuk peldaul (konkretan ebben a hardver-felallasban amin tesztelek) 48MHz-n menne az egyetlen clock es csak minden 4ik orajelre van egy CE=1 allapot: mert attol meg a processzoron beluli critical parth az tul hosszu marad ehhez (most olyan 24MHz-re huzhato biztonsaggal). Viszont a dmem_* buszon levo wait state lehetoseg mar segit(het)i ezt az illesztest.

Igazsag szerint nincs nincs annyi konkret tapasztalatom ezen a SoC szinten clock domain illesztesre, de pont a dmem_* wait state miatt tervezem kiprobalni hamarost azt hogy az FPGA configuration NOR flash-t belelapozom az AVR memoriajaba, igy kiserletezes cimszo alatt. Es akkor a flash SPI clockja az mondjuk jarhat 40MHz-n (80MHz core clock + /2 prescaler), az azt jelenti hogy egy byte effektiven 5MHz-nak megfelelo ido  alatt kiolvashato. Azaz egy 12MHz-s CPU 2-3 orajel alatt azert megkapja (es ha van par byte prefetch/cache, akkor akar 1 cycle alatt is, ha meg cimezni kell meg elotte akkor azert 10-12 orajel is kell a legelso byte-hoz). Szoval kiserletnek pont jo lesz. 

Ha 48MHz-et kap az AVR, de csak minden 2. ütemre CE-t, akkor egy multicylce path definíciója után a szintézis tool úgy tudja kezelni majd, mintha 24 MHz-en menne.

A clock-domain crossing az sosem jó, pláne, ha aszinkron órajelekről van szó. Szinkronziáló láncok, dual-clock FIFOk és egyéb trükkök kellenek, hogy ne legyen instabil az egész.

Igen, akkor sokkal kisebb a szivas ha fazisban vannak az orajelek. Es altalaban pont forditott a helyzet (ehhez a SoC-hoz kepest), hogy a fo orajel a CPU core es a periferiak orajeli vannak belassitva - altalaban egesz es/vagy ketto-hatvanynak megfelelo osztokkal. Es a teljesen fuggetlen clock domain-ek (pl RTC, WDT) meg annyia lassuak eleve hogy ott egy dual port FIFO mar nem szuk keresztmetszet...