<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.electroniciens.cnrs.fr/index.php?action=history&amp;feed=atom&amp;title=FPGA_CPLD_%3A_Guides_%3A_AXI4-Stream</id>
	<title>FPGA CPLD : Guides : AXI4-Stream - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.electroniciens.cnrs.fr/index.php?action=history&amp;feed=atom&amp;title=FPGA_CPLD_%3A_Guides_%3A_AXI4-Stream"/>
	<link rel="alternate" type="text/html" href="https://wiki.electroniciens.cnrs.fr/index.php?title=FPGA_CPLD_:_Guides_:_AXI4-Stream&amp;action=history"/>
	<updated>2026-06-21T23:40:57Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.electroniciens.cnrs.fr/index.php?title=FPGA_CPLD_:_Guides_:_AXI4-Stream&amp;diff=2781&amp;oldid=prev</id>
		<title>William.benharbone le 2 mars 2016 à 17:39</title>
		<link rel="alternate" type="text/html" href="https://wiki.electroniciens.cnrs.fr/index.php?title=FPGA_CPLD_:_Guides_:_AXI4-Stream&amp;diff=2781&amp;oldid=prev"/>
		<updated>2016-03-02T17:39:02Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Liens utiles ==&lt;br /&gt;
{| class=&amp;quot;wikitable centre&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;#039;&amp;#039;&amp;#039;Documentations :&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;lt;div id=&amp;quot;AMBA&amp;quot;&amp;gt; [http://www.arm.com/products/system-ip/amba-specifications.php Specification AMBA4 AXI4-Stream Protocol.pdf] : Document de référence pour la protocole AXI4-Stream &amp;lt;/div&amp;gt;&lt;br /&gt;
*[[Media:Xilinx AXI Reference Guide.pdf|Xilinx AXI Reference Guide.pdf]] : Guide d&amp;#039;utilisation de l&amp;#039;AXI4 avec les IP Xilinx&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&lt;br /&gt;
L&amp;#039;AXI4-Stream n&amp;#039;est qu&amp;#039;une déclinaison du protocole AXI (Advanced eXtensible Interface), qui lui-même prend en compte la spécification AMBA (Advanced Microcontroller Bus Architecture) . Dans la plupart des cas, dans un design VHDL, le AXI4-Stream est suffisant.&lt;br /&gt;
&lt;br /&gt;
Beaucoup de modules IP Xilinx, surtout lorsqu&amp;#039;ils sont compatibles avec le [http://www.xilinx.com/tools/microblaze.htm MicroBlaze] utilisent le protocole AXI4-Stream.&lt;br /&gt;
&lt;br /&gt;
La plupart du temps, on utilise le même genre de protocole sans savoir qu&amp;#039;il est normalisé par l&amp;#039;AXI4-Stream. En l&amp;#039;utilisant, on s&amp;#039;assure néanmoins de pouvoir interchanger facilement et rapidement des modules respectant ce protocole.&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement ==&lt;br /&gt;
&lt;br /&gt;
Le protocole AXI4-Stream est un protocole avec handshake qui utilise entre 2 et 9 signaux pour communiquer. Dans la communication, on définit un maître et un esclave. Le maître est l&amp;#039;émetteur de la donnée et l&amp;#039;esclave la reçoit. Les deux signaux qui sont obligatoires sont les signaux :&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TDATA&amp;#039;&amp;#039;&amp;#039; : vecteur de la donnée&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; : indique qu&amp;#039;une donnée est présente et valide pour l&amp;#039;esclave&lt;br /&gt;
Dans la plupart des cas, on va utiliser un signal supplémentaire :&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; : flag présenté par l&amp;#039;esclave pour indiquer qu&amp;#039;il est prêt à recevoir la donnée.&lt;br /&gt;
&lt;br /&gt;
Il est possible de se passer du signal &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; et dans ce cas, on considère que la transmission se fait sans confirmation de la part de l&amp;#039;esclave.&lt;br /&gt;
&lt;br /&gt;
Les autres signaux que l&amp;#039;on peut utiliser dans le transfert sont les suivants :&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TID&amp;#039;&amp;#039;&amp;#039; : Permet d&amp;#039;identifier la trame en cours de transmission (dans le cas où des trames différentes seraient transmises de façon entrelacées)&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TDEST&amp;#039;&amp;#039;&amp;#039; : Fonctionne comme un adresse de destination dans le cas de plusieurs esclaves ou de plusieurs destinations dans l&amp;#039;esclave.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TLAST&amp;#039;&amp;#039;&amp;#039; : Indique la fin d&amp;#039;une trame, utile lorsque les trames sont de tailles variables&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TKEEP&amp;#039;&amp;#039;&amp;#039; : Permet d&amp;#039;indiquer si la donnée transmise doit être prise en compte dans la trame&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TSTRB&amp;#039;&amp;#039;&amp;#039; : Indique si la donnée est une donnée utile ou un octet de positionnement. L&amp;#039;octet de positionnement peut permettre de ne mettre à jour qu&amp;#039;une partie des informations détenus par l&amp;#039;esclave, par exemple si on écrit de façon contigüe dans des registres, on peut sauter l&amp;#039;un d&amp;#039;eux. c&amp;#039;est ce qui fait la différence avec le signal &amp;#039;&amp;#039;&amp;#039;TKEEP&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TUSER&amp;#039;&amp;#039;&amp;#039; : Vecteur de données parallèle à la donnée principale qui peut comporter d&amp;#039;autres informations à destination de l&amp;#039;esclave ou passer à travers avec une latence prédéterminée pour correspondre à la latence de la donnée principale.&lt;br /&gt;
&lt;br /&gt;
Nous allons considérer le cas le plus simple, qui comprend les trois signaux de base. Pour plus de détails sur le fonctionnement complet du protocole, veuillez vous reporter à la spécification.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;/!\ Pour ce qui va suivre, ouvrez la spécification [[#AMBA|AMBA]] à la page 19.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dans le cas où on utilise le signal &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039;, on considère trois cas de figures :&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; est présent avant &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; : &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; est actif jusqu&amp;#039;à ce que &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; le soit aussi. Sauf si une nouvelle donnée est présentée, il est désactivé aussitôt.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; est présent avant &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; : La donnée est prise en compte dès son arrivée et &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; est désactivé aussitôt. &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; peut rester actif si l&amp;#039;esclave peut accueillir plusieurs données à la suite.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;TVALID&amp;#039;&amp;#039;&amp;#039; et &amp;#039;&amp;#039;&amp;#039;TREADY&amp;#039;&amp;#039;&amp;#039; sont présents en même temps : Ils sont alors désactivés en même temps au front d&amp;#039;horloge suivant sauf si comme les cas précédents une nouvelle donnée est présente ou que l&amp;#039;esclave est toujours prêt à recevoir une donnée.&lt;br /&gt;
&lt;br /&gt;
== Exemples ==&lt;br /&gt;
&lt;br /&gt;
On choisit de représenter l&amp;#039;architecture suivante pour représenter différents cas de figure.&lt;br /&gt;
&lt;br /&gt;
[[Image:VHDL - AXI4 Exemple.jpg|frameless|center|600px|VHDL - AXI4 Exemple]]&lt;br /&gt;
&lt;br /&gt;
Le module 1 est le maître par rapport à la FIFO et la FIFO est le maître par rapport au module 2. Il n&amp;#039;est pas nécessaire de connaître le fonctionnement des modules 1 et 2. Pour l&amp;#039;exemple, on considère que ces modules ont des comportements anarchiques et que des données peuvent sortir à n&amp;#039;importe quel moment du module 1 et que le module 2 peut les accepter à intervalle irrégulier. &lt;br /&gt;
&lt;br /&gt;
Ces comportement ne sont pas si exceptionnels que l&amp;#039;on pourrait le penser. Ils peuvent être typiquement ceux de modules de communication dans des interface de types conversion de I²C vers UART ou Ethernet vers SPI (pour prendre deux exemples au hasard). Pour vous en convaincre, vous pouvez regarder le schéma bloc (page 3) du [http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232BL_BQ.pdf FT232B].&lt;br /&gt;
&lt;br /&gt;
On nomme les signaux ainsi :&lt;br /&gt;
* Entre le module 1 et la FIFO : &amp;#039;&amp;#039;&amp;#039;TDATA_1F&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;TVALID_1F&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Entre la FIFO et le module 2 : &amp;#039;&amp;#039;&amp;#039;TDATA_F2&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;TVALID_F2&amp;#039;&amp;#039;&amp;#039;, &amp;#039;&amp;#039;&amp;#039;TREADY_F2&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dans le fonctionnement de la FIFO, le signal &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039; est valide lorsque la FIFO n&amp;#039;est pas pleine. Dès que trois données sont stockées dans la FIFO, le signal &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039; passe à l&amp;#039;état bas, ce qui doit empêcher le maître d&amp;#039;ajouter de nouvelles données. Le signal &amp;#039;&amp;#039;&amp;#039;TVALID_F2&amp;#039;&amp;#039;&amp;#039; est actif si au moins une donnée est stockée dans la FIFO. La donnée est effectivement transmise si &amp;#039;&amp;#039;&amp;#039;TREADY_F2&amp;#039;&amp;#039;&amp;#039; est actif.&lt;br /&gt;
&lt;br /&gt;
La FIFO a la particularité de pouvoir anticiper si une place va se libérer en observant si le module 2 va lire la donnée au coup d&amp;#039;horloge suivant.&lt;br /&gt;
&lt;br /&gt;
Pour mieux suivre les problèmes d&amp;#039;embouchure, on présentera dans les chronogrammes le compteur de donnée présentes dans la FIFO.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Exemple n°1 :&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dans ce premier exemple, on ne considère que le module 1 et la FIFO. Le module 1 va remplir la FIFO et attend qu&amp;#039;il y ait de la place pour y stocker sa donnée courante.&lt;br /&gt;
&lt;br /&gt;
[[Image:VHDL - AXI4 Exemple 1.jpg|frameless|center|350px|VHDL - AXI4 Exemple 1]]&lt;br /&gt;
&lt;br /&gt;
Lors des fronts d&amp;#039;horloge 3, 4 et 5, les données D0, D1 et D2 sont stockées dans la FIFO. A partir de là, la FIFO indique qu&amp;#039;il n&amp;#039;y a plus de place en positionnement &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039; à l&amp;#039;état bas. &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039; repasse à &amp;#039;1&amp;#039; quelques instants plus tard ce qui permet au module 1 de stocker sa donnée suivante D3.&lt;br /&gt;
&lt;br /&gt;
Notez que le compteur est toujours à 3 lorsque &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039; repasse à l&amp;#039;état haut. La FIFO sait que le module 2 va lire la donnée D0 au front n°8 ce qui va libérer une place. Le compteur reste donc à 3 (une donnée sortante et une donnée entrante en même temps).&lt;br /&gt;
&lt;br /&gt;
De ce chronogramme, on pourrait supposer que le module 1 est plus rapide que le module 2 et que l&amp;#039;on risque de perdre des données si la FIFO n&amp;#039;est pas assez grande pour stocker toute les données envoyées par le module 1.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Exemple n°2 :&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Dans cet exemple très simple, on suppose que le module 2 est plus rapide que le module 1 et donc que la donnée stockée est immédiatement lue.&lt;br /&gt;
&lt;br /&gt;
[[Image:VHDL - AXI4 Exemple 2.jpg|frameless|center|350px|VHDL - AXI4 Exemple 2]]&lt;br /&gt;
&lt;br /&gt;
Dans un cas dans celui-là, la FIFO ne serait pas nécessaire car elle n&amp;#039;est jamais remplie qu&amp;#039;avec une donnée. Les modules 1 et 2 pourrait être reliè directement en AXI4.&lt;br /&gt;
&lt;br /&gt;
*&amp;#039;&amp;#039;&amp;#039;Exemple n°3 :&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pour cet exemple, vous allez devoir compléter le chronogramme suivant en fonction des signaux présentés. &amp;#039;&amp;#039;&amp;#039;Très important :&amp;#039;&amp;#039;&amp;#039; on considère que le module 1 ne se soucie pas de l&amp;#039;état de &amp;#039;&amp;#039;&amp;#039;TREADY_1F&amp;#039;&amp;#039;&amp;#039;, il envoie les données sans vérification.&lt;br /&gt;
&lt;br /&gt;
[[Image:VHDL - AXI4 Exemple 3 Masqué.jpg|frameless|center|600px|VHDL - AXI4 Exemple 3 Masqué]]&lt;br /&gt;
&lt;br /&gt;
Vérifiez votre réponse ci-dessous et lisez les explications.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;toccolours mw-collapsible mw-collapsed&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solution&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:VHDL - AXI4 Exemple 3.jpg|frameless|center|600px|VHDL - AXI4 Exemple 3]]&lt;br /&gt;
&lt;br /&gt;
* Lors des fronts d&amp;#039;horloge 2 et 3, des données sont stockées, ce qui positionne &amp;#039;&amp;#039;&amp;#039;TVALID_F2&amp;#039;&amp;#039;&amp;#039; à &amp;#039;1&amp;#039; et incrémente le compteur. &lt;br /&gt;
* Au front 6, une donnée est lue et une donnée est stockée, le compteur reste à 2.&lt;br /&gt;
* Au front 7, une donnée est stockée, ce qui porte le compteur à 3.&lt;br /&gt;
* Aux front 8 et 9, des données sont lues, le compteur redescend à 1.&lt;br /&gt;
* Aux front 10 et 12, deux données sont à nouveau stockées, ce qui porte le compteur à 3.&lt;br /&gt;
* Aux front 14 et 15, les données ne peuvent pas être stockées car la FIFO est pleine et elles seront complétement perdues.&lt;br /&gt;
* Aux front 16 et 17, les données sont en même temps lues et stockées, le compteur reste à 3.&lt;br /&gt;
* Au front 19, une donnée est stockée et une donnée est lue, là aussi le compteur reste à 3. Comme les données D6 et D7 n&amp;#039;ont pas pu être stockées, c&amp;#039;est la donnée D8 qui vient après la donnée D5 en sortie sur &amp;#039;&amp;#039;&amp;#039;TDATA_F2&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>William.benharbone</name></author>
	</entry>
</feed>