.. _w07-axi: ================================== WykĹad 7: Komunikacja z procesorem ================================== Data: 08.12.2020 .. toctree:: .. contents:: O rejestrach MMIO i szynach systemowych ======================================= CzÄĹciÄ praktycznie kaĹźdego bardziej skomplikowanego ukĹadu cyfrowego jest procesor (a czÄsto wiele procesorĂłw), ktĂłry steruje pracÄ caĹoĹci bÄ dĹş czÄĹci ukĹadu. Procesor musi mieÄ moĹźliwoĹÄ komunikacji z kaĹźdÄ istotniejszÄ czÄĹciÄ takiego ukĹadu. IstniejÄ dwa podejĹcia do podĹÄ czenia urzÄ dzeĹ do procesora: - ciasna integracja: urzÄ dzenie ma swĂłj dedykowany interfejs i staje siÄ w pewnym sensie czÄĹciÄ specyfikacji procesora (np. dedykowane instrukcje czy specjalne rejestry procesora do obsĹugi danego urzÄ dzenia) - luĹşna integracja: urzÄ dzenie jest podĹÄ czone do procesora przez standardowÄ szynÄ (zazwyczaj wspĂłĹdzielonÄ z innymi urzÄ dzeniami) i jest widoczne dla procesora za pomocÄ zwykĹych instrukcji dostÄpu do pamiÄci â pewna czÄĹÄ fizycznej przestrzeni adresowej jest wydzielona dla urzÄ dzenia i odpowiada ono na instrukcje procesora ktĂłre piszÄ bÄ dĹş czytajÄ ten obszar; podejĹcie takie nazywa siÄ MMIO (memory-mapped I/O) Ciasna integracja jest uĹźywana rzadko (najczÄĹciej gdy projektujemy jednoczeĹnie procesor i jego urzÄ dzenia peryferyjne) i w przypadku procesorĂłw ogĂłlnego przeznaczenia uĹźywa siÄ wyĹÄ cznie luĹşnej integracji. SzynÄ systemowÄ nazywamy zbiĂłr poĹÄ czeĹ, ktĂłry ĹÄ czy ze sobÄ procesory (i inne urzÄ dzenia bÄdÄ ce w stanie inicjowaÄ transakcje) z urzÄ dzeniami peryferyjnymi. MoĹźe to byÄ doĹÄ prosty bÄ dĹş bardzo skompilokowany byt â moĹźe skĹadaÄ siÄ z naprawdÄ wielu segmentĂłw wykonanych w wielu technologiach, moĹźe byÄ zawarta w ramach jednego ukĹadu scalonego, bÄ dĹş teĹź skĹadaÄ siÄ z wielu ukĹadĂłw i poĹÄ czeĹ (byÄ moĹźe kablowych). Charakteryzuje siÄ nastÄpujÄ cymi cechami: - szyna ma jednego lub wiÄcej inicjatorĂłw â urzÄ dzenia, ktĂłre mogÄ inicjowaÄ transakcje na szynie; oczywistym przykĹadem inicjatora jest procesor, ale inicjatorami sÄ teĹź np. urzÄ dzenia peryferyjne bÄdÄ ce w stanie wykonywaÄ operacje bezpoĹredniego dostÄpu do pamiÄci (DMA) - szyna ma jeden bÄ dĹş wiÄcej targetĂłw â urzÄ dzeĹ, ktĂłre mogÄ odpowiadaÄ na transakcje - gĹĂłwna pamiÄÄ systemu rĂłwnieĹź jest targetem (pokrywajÄ cym duĹźy zakres adrwsĂłw) - standardowe transakcje na szynie to transakcje odczytu i zapisu (ale zdarzajÄ siÄ dziwniejsze typy transakcji na niektĂłrych szynach); transakcje odczytu i zapisu skĹadajÄ siÄ z co najmniej: - adresu docelowego (wysyĹanego przez inicjatora) - rozmiaru (w bajtach) â jeĹli jest wiÄkszy niĹź 1, transakcja pokrywa wiele kolejnych adresĂłw - danych (wysyĹane przez inicjatora w przypadku zapisu, przez target w przypadku odczytu) â target dla danej transakcji jest wybierany na podstawie jej adresu â kaĹźdemu targetowi jest przydzielony jakiĹ zakres (bÄ dĹş zakresy) adresĂłw; w ramach swoich zakresĂłw target moĹźe dowolnie interpretowaÄ resztÄ adresu - mapowanie adresĂłw na urzÄ dzenia moĹźe byÄ kompletnie ustalone w momencie produkcji ukĹadu (w przypadku szyn mieszczÄ cych siÄ w caĹoĹci w jednym ukĹadzie) bÄ dĹş mniej lub bardziej konfigurowalne (w przypadku bardziej skomplikowanych szyn, jak te w komputerach klasy PC) - choÄ zazwyczaj kaĹźdy inicjator na szynie widzi takie samo mapowanie adresĂłw, nie zawsze jest to prawda â mogÄ istnieÄ targety niedostÄpne z czÄĹci szyny - zdarzajÄ siÄ szyny z tzw. IOMMU â ukĹadami tĹumaczÄ cymi adresy; w takim wypadku, transakcje od niektĂłrych inicjatorĂłw przechodzÄ przez tĹumaczenie adresĂłw bardzo podobne do stronicowania przez procesor - szyna moĹźe skĹadaÄ siÄ z wielu róşnych pod-szyn wykonanych w róşnych techonologiach i poĹÄ czonych mostkami, bÄ dĹş switchami UkĹady SoC i AMBA ================= UkĹady SoC (system on a chip) to ukĹady, ktĂłre zawierajÄ procesor wraz z doĹÄ kompletnym zestawem urzÄ dzeĹ peryferyjnych, pozwalajÄ c na zĹoĹźenie kompletnego systemu z minimalnÄ liczbÄ zewnÄtrznych ukĹadĂłw (zazwyczaj tylko DRAM + flash). Taki ukĹad jest sercem kaĹźdego wspĂłĹczesnego telefonu czy tableta. Takim ukĹadem jest rĂłwnieĹź uĹźywany przez nas Zynq. AMBA to zbiĂłr standardĂłw stworzonych przez ARM opisujÄ cych technologie komunikacji pomiÄdzy urzÄ dzeniami zawartymi w jednym ukĹadzie scalonym, w tym technologie sĹuĹźÄ ce do realizacji szyny systemowej. W skĹad AMBA wchodzÄ miÄdzy innymi: - szyna AXI (Advanced eXtensible Interface) â gĹĂłwny interfejs uĹźywany przez wspĂłĹczesne duĹźe procesory ARM i ukĹady SoC na nich oparte; jest to interfejs point-to-point: komunikacja odbywa siÄ pomiÄdzy jednym inicjatorem a jednym targetem i naleĹźy uĹźyÄ switcha AXI, by mĂłc spiÄ Ä ze sobÄ wiÄcej urzÄ dzeĹ; jest oparty o 5 strumieni valid-ready i pozwala na jednoczesne wykonywanie wielu transakcji w potoku; ma wiele wersji: - AXI3: pierwsza wersja (uĹźywana na Zynq) - AXI4 - AXI5 - AXI4-Lite: uproszczone AXI4 - AXI5-Lite - ACE (AXI Coherency Extensions): wersja AXI4 z dodatkowymi operacjami pozwalajÄ cymi na Ĺledzenie stanu pamiÄci cache - ACE-Lite - ACE5: ACE, ale na bazie AXI5 - szyna AHB (Advanced High-performance Bus) â poprzednik AXI, oparty o zupeĹnie inny schemat; jest to szyna wielodostÄpna (jest wielu inicjatorĂłw, w kaĹźdym cyklu jeden z nich ma dostÄp do szyny, wybrany przez arbitra), z wieloma targetami; uĹźywana w starszych (bÄ dĹş mniejszych) procesorach ARM; istnieje teĹź wariant AHB-Lite, w ktĂłrym istnieje tylko jeden inicjator - szyna APB (Advanced Peripherial Bus) â doĹÄ prosty interfejs; ma jednego inicjatora i wiele targetĂłw, nie ma Ĺźadnej moĹźliwoĹci przetwarzania potokowego ani rĂłwnolegĹego; jest uĹźywana na "koĹcĂłwkach" szyny systemowej, ktĂłre nie wymagajÄ zbyt duĹźej wydajnoĹci (czyli wolne urzÄ dzenia peryferyjne, bÄ dĹş rzadko uĹźywane rejestry MMIO) Zynq 7000 --------- Zynq jest (poza czÄĹciÄ z FPGA) doĹÄ typowym ukĹadem typu SoC bazujÄ cym na procesorze ARM. Zawiera: - procesor ARM Cortex-A9 - 256kB wewnÄtrznego RAMu - kontroler pamiÄci DDR pozwalajÄ cy na podĹÄ czenie do 1GB zewnÄtrznego RAMu - doĹÄ nietrywialnÄ sieÄ szyn AXI i switchy stanawiÄ cÄ szkielet szyny systemowej - kilka szyn APB, do ktĂłrych podĹÄ czone sÄ ukĹady peryferyjne - kilka szyn AXI ĹÄ czÄ cych szynÄ systemowÄ z FPGA i pozwalajÄ cych na rozszerzenie jej przez ukĹad uĹźytkownika: - ``SAXI_HP[0-3]``: 4 szybkie i szerokie (64-bit) szyny AXI, w ktĂłrych FPGA jest inicjatorem, podĹÄ czone do switcha, ktĂłry widzi tylko RAM (ten wbudowany i ten zewnÄtrzny) â pozwala na wydajny dostÄp do pamiÄci - ``SAXI_GP[0-1]``: 2 32-bitowe szyny AXI, w ktĂłrych FPGA jest inicjatorem, podĹÄ czone do switcha, z ktĂłrego dostÄpna jest caĹa gĹĂłwna przestrzeĹ adresowa urzÄ dzenia â pozwala na dostÄp do (prawie) wszystkich targetĂłw - ``SAXI_ACP``: 64-bitowa szyna AXI, w ktĂłrej FPGA jest inicjatorem, podĹÄ czone do kontrolera pamiÄci cache w procesorze â pozwala na dostÄp do caĹej przestrzeni adresowej widzianej przez procesor w sposĂłb spĂłjny z jego cachem (pozostaĹe szyny ``SAXI_*`` pomijajÄ cache) - ``MAXI_GP[0-1]``: 2 32-bitowe szyny AXI, w ktĂłrych FPGA jest targetem; pozwala innym urzÄ dzeniom na wysyĹanie transakcji do FPGA; szyna ``MAXI_GP0`` ma przydzielony zakres adresĂłw ``0x40000000:0x80000000``, a szyna ``MAXI_GP1`` â ``0x80000000:0xc0000000`` - kilka ukĹadĂłw peryferyjnych, ktĂłre majÄ moce DMA i majÄ szynÄ AXI ĹÄ czÄ cÄ je (jako inicjator) z resztÄ systemu - dwie szyny AHB-Lite, ktĂłrymi podĹÄ czone sÄ do gĹĂłwnej sieci kontrolery SDIO (bo akurat takie kupili) - wolnostojÄ cy kontroler DMA, pozwalajÄ cy na przesyĹ danych miÄdzy pamiÄciÄ a peryferiami (w przypadku Zynq, jedynym podĹÄ czonym urzÄ dzeniem peryferyjnym jest FPGA) Szyna AXI ========= PeĹny opis szyny AXI moĹźna znaleĹşÄ w dokumentacji: https://developer.arm.com/documentation/ihi0022/e/AMBA-AXI3-and-AXI4-Protocol-Specification?lang=en . Tutaj opowiemy tylko o najwaĹźniejszych elementach. Szyna AXI3 (w wersji zaimplementowanej w Zynq) skĹada siÄ z nastÄpujÄ cych poĹÄ czeĹ: - sygnaĹy sterujÄ ce: ``ACLK`` (zegar) i ``ARESETN`` (zanegowany reset), wspĂłlne dla wszystkich 5 strumieni; w przypadku interfejsĂłw FPGA na Zynq, sÄ sterowane ze strony FPGA (Zynq zawiera odpowiedni mostek, ktĂłry przeniesie dane z/do wewnÄtrznych domen zegarowych i moĹźemy uĹźyÄ dowolnego zegara nie wiÄkszego niĹź 250 MHz) - strumieĹ ĹźÄ daĹ odczytu (od inicjatora do targetu) â sĹuĹźy do rozpoczynania transakcji odczytu: - ``ARVALID``, ``ARREADY`` - ``ARADDR`` (32-bitowy): adres ĹźÄ danego odczytu - ``ARID`` (róşnej dĹugoĹci): identyfikator inicjatora transakcji â peĹny identyfikator inicjatora w caĹym Zynq ma 12 bitĂłw, ale tylko czÄĹÄ jest przydzielona do wyboru przez naszÄ szynÄ (pozostaĹe bity sÄ wypeĹniane przez sieÄ poĹÄ czeĹ i identyfikujÄ port, z ktĂłrego wysĹaliĹmy transakcjÄ) - ``MAXI_GP*``: 12 bitĂłw (jako target widzimy caĹy identyfikator inicjatora) - ``SAXI_ACP``: 3 bity (pozostaĹe bity identyfikatora wskazujÄ na procesor, a wewnÄ trz procesora na port ACP) - ``SAXI_GP*``: 6 bitĂłw (pozostaĹe bity identyfikatora wskazujÄ na naszÄ szynÄ) - ``SAXI_HP*``: 6 bitĂłw (pozostaĹe bity identyfikatora wskazujÄ na naszÄ szynÄ) - ``ARBURST`` (2-bitowy): typ transakcji: - 0: ``FIXED`` â wszystkie transfery w transakcji majÄ ten sam adres - 1: ``INCR`` â kolejne transfery w transakcji majÄ kolejno rosnÄ ce (o rozmiar transferu) adresy - 2: ``WRAP`` â doĹÄ skomplikowany tryb, podobny do ``INCR``, ale ze specjalnymi zasadami zawijania; uĹźywany do wczytywania caĹej linii cache zaczynajÄ c od wybranego sĹowa - ``ARSIZE`` (2-bitowy): rozmiar jednego transferu danych, dekodowany nastÄpujÄ co: - 0: 1 bajt - 1: 2 bajty - 2: 4 bajty - 3: 8 bajtĂłw (tylko na szynach 64-bitowych) - ``ARLEN`` (4-bitowy): rozmiar transakcji w transferach pomniejszony o 1 (czyli 0 w tym polu oznacza 1 transfer; 5 oznacza 6 transferĂłw) - ``ARCACHE`` (4-bitowy): atrybuty cacheowalnoĹci transakcji (moĹźna tu podaÄ 0 jako inicjator) - ``ARLOCK`` (2-bitowy): atrybuty atomowoĹci transakcji (naleĹźy tu podaÄ 0 jako inicjator) - ``ARPROT`` (3-bitowy): atrybuty zabezpieczeĹ transakcji (moĹźna tu podaÄ 0 jako inicjator) - ``ARQOS`` (4-bitowy): atrybuty priorytetu transakcji (moĹźna tu podaÄ 0 jako inicjator) - ``ARUSER`` (5-bitowy, tylko na ``SAXI_ACP``): specjalne atrybuty transakcji (naleĹźy to podaÄ 0 jako inicjator) - strumieĹ danych odczytu (od targetu do inicjatora) â sĹuĹźy do przesyĹania odczytanych danych w transakcji odczytu i koĹczenia transakcji odczytu: - ``RVALID``, ``RREADY`` - ``RDATA`` (32-bitowe lub 64-bitowe): wĹaĹciwe dane - ``RID`` (róşnej dĹugoĹci): rĂłwne ``ARID`` odczytu, ktĂłrego dane dotyczÄ - ``RLAST`` (1-bitowe): prawda, jeĹli to ostatni transfer danych z transakcji, koĹczy transakcjÄ - ``RRESP`` (2-bitowe): typ odpowiedzi: - 0: ``OKAY`` â udana transakcja - 1: ``EXOKAY`` â udana transakcja z wyĹÄ cznoĹciÄ - 2: ``SLVERR`` â transakcja odrzucona przez target - 3: ``DECERR`` â transakcja odrzucona przez szynÄ (adres nie odpowiada Ĺźadnemu targetowi) - strumieĹ ĹźÄ daĹ zapisu (od inicjatora do targetu) â sĹuĹźy do rozpoczynania transakcji zapisu: - ``AWVALID``, ``AWREADY`` - ``AWADDR`` (32-bitowy): adres ĹźÄ danego zapisu - ``AWID`` (róşnej dĹugoĹci): analogicznie do ``ARID`` - ``AWBURST`` (2-bitowy): analogicznie do ``ARBURST`` - ``AWSIZE`` (2-bitowy): analogicznie do ``ARSIZE`` - ``AWLEN`` (4-bitowy): analogicznie do ``ARLEN`` - ``AWCACHE`` (4-bitowy): analogicznie do ``ARCACHE`` - ``AWLOCK`` (2-bitowy): analogicznie do ``ARLOCK`` - ``AWPROT`` (3-bitowy): analogicznie do ``ARPROT`` - ``AWQOS`` (4-bitowy): analogicznie do ``ARQOS`` - ``AWUSER`` (5-bitowy, tylko na ``SAXI_ACP``): analogicznie do ``ARUSER`` - strumieĹ danych zapisu (od inicjatora do targetu) â sĹuĹźy do przesyĹania zapisywanych danych w transakcji zapisu: - ``WVALID``, ``WREADY`` - ``WDATA`` (32-bitowe lub 64-bitowe): wĹaĹciwe dane - ``WID`` (róşnej dĹugoĹci): rĂłwne ``ARID`` odczytu, ktĂłrego dane dotyczÄ - ``WLAST`` (1-bitowe): prawda, jeĹli to ostatni transfer danych z transakcji, koĹczy transakcjÄ - ``WSTRB`` (4-bitowe dla 32-bitowej szyny, 8-bitowe dla 64-bitowej szyny): sygnaĹy byte enable dla poszczegĂłlnych bajtĂłw, wybierajÄ ktĂłre bajty w sĹowie faktycznie naleĹźy zapisaÄ - strumieĹ odpowiedzi na zapisy (od targetu do inicjatora) â koĹczy transakcjÄ zapisu: - ``BVALID``, ``BREADY`` - ``BID`` (róşnej dĹugoĹci): identyfikator inicjatora transakcji â rĂłwne ``AWID`` zapisu, na ktĂłry odpowiada - ``BRESP`` (2-bitowe): typ odpowiedzi, analogiczne do ``RRESP`` Strumienie w AXI sÄ wariantem opisanych wczeĹniej interfejsĂłw valid-ready z nastÄpujÄ cymi wymaganiami: - gdy wysyĹajÄ cy ustawi sygnaĹ valid na 1, nie wolno mu ustawiÄ go na 0 ani zmieniÄ pakietu dopĂłki pakiet nie zostanie zaakceptowany przez odbierajÄ cego (czyli gdy ready bÄdzie rĂłwne 1) â nie wolno "zrezygnowaÄ" z przesyĹu pakietu - nie wolno mieÄ Ĺźadnych ĹcieĹźek kombinacyjnych miÄdzy ĹźadnÄ parÄ sygnaĹĂłw w interfejsie Zasady dziaĹania transakcji AXI sÄ nastÄpujÄ ce: 1. Transakcja skĹada siÄ z jednego lub wiÄcej transferĂłw, gdzie transfer ma dowolnÄ dĹugoĹÄ bÄdÄ cÄ potÄgÄ dwĂłjki od 1 bajtu do szerokoĹci szyny. 2. Bajt o adresie X jest zawsze transferowany na bitach ``(X * 8 % DATA_WIDTH) : (X * 8 % DATA_WIDTH) + 8`` szyny danych. 3. Wszystkie adresy w ramach jednej transakcji muszÄ zawieraÄ siÄ w tym samym wyrĂłwnanym bloku 4kB. 4. JeĹli adres transakcji nie jest wyrĂłwnany do rozmiaru transferu, tylko czÄĹÄ bajtĂłw w pierwszym transferze zostanie przetransferowana; w pozostaĹych transferach zostanie juĹź przetransferowany peĹny rozmiar. 5. Targety bÄdÄ ce pamiÄciÄ muszÄ wspieraÄ wszystkie typy i rozmiary transakcji. Targety bÄdÄ ce rejestrami MMIO mogÄ ograniczyÄ siÄ do wybranego podzbioru. 6. Zawsze przesyĹane jest dokĹadnie tyle danych, ile zostaĹo wczeĹniej zadeklarowane (nawet w przypadku bĹÄdu). 7. Zapis wyglÄ da nastÄpujÄ co: 1. Inicjator wysyĹa na strumieniu ``AW*`` pakiet z adresem i metadanymi transakcji. 2. Inicjator wysyĹa na strumieniu ``W*`` pakiety z danymi transakcji (tyle pakietĂłw, ile jest transferĂłw w transakcji). Ostatni pakiet w transakcji (i tylko on) ma ustawiony bit ``WLAST``. PrzesyĹ danych moĹźe odbywaÄ siÄ rĂłwnolegle z przesyĹem adresu. 3. Wszystkie pakiety na strumieniu ``W*`` muszÄ byÄ wysyĹane w takiej samej kolejnoĹci co odpowiadajÄ ce pakiety na strumieniu ``AW*``. 4. Gdy target odbierze wszystkie pakiety odpowiadajÄ ce jednej transakcji, wysyĹa na strumieniu ``B*`` jeden pakiet z odpowiedziÄ (nie wolno zrobiÄ tego przed otrzymaniem wszystkich danych). 5. Inicjator nie musi czekaÄ na odpowiedĹş przed rozpoczÄciem kolejnego zapisu â tempo wysyĹania transakcji ograniczone jest tylko sygnaĹami gotowoĹci targetu. 6. W ramach jednego identyfikatora ``AWID/WID/BID``, odpowiedzi bÄdÄ zawsze przychodziÄ w takiej samej kolejnoĹci, w jakiej zapisy zostaĹy wysĹane. 7. Switchom i targetom wolno jednak dowolnie przestawiaÄ zapisy o róşnych identyfikatorach ``AWID/WID/BID`` â odpowiedzi mogÄ teĹź przyjĹÄ w dowolnej kolejnoĹci. 8. Odczyt wyglÄ da nastÄpujÄ co: 1. Inicjator wysyĹa na strumieniu ``AR*`` pakiet z adresem i metadanymi transakcji. 2. Target wysyĹa na strumieniu ``R*`` pakiety z danymi transakcji (tyle pakietĂłw, ile ma byÄ transferĂłw w transakcji). Ostatni pakiet w transakcji (i tylko on) ma ustawiony bit ``RLAST``. 3. Inicjator nie musi czekaÄ na odpowiedĹş przed rozpoczÄciem kolejnego odczytu â tempo wysyĹania transakcji ograniczone jest tylko sygnaĹami gotowoĹci targetu. 4. W ramach jednego identyfikatora ``ARID/RID``, odpowiedzi bÄdÄ zawsze przychodziÄ w takiej samej kolejnoĹci, w jakiej odczyty zostaĹy wysĹane. 5. Switchom i targetom wolno jednak dowolnie przestawiaÄ odczyty o róşnych identyfikatorach ``ARID/RID`` â odpowiedzi mogÄ teĹź przyjĹÄ w dowolnej kolejnoĹci. 9. Odczyty i zapisy sÄ niezaleĹźnymi strumieniami i mogÄ byÄ dowolnie przestawiane miÄdzy sobÄ â jeĹli inicjator chce, by miaĹy ustalonÄ kolejnoĹÄ, powinien poczekaÄ na odpowiedĹş na pierwszÄ transakcjÄ przed wysĹaniem drugiej.