Wikilivres
frwikibooks
https://fr.wikibooks.org/wiki/Accueil
MediaWiki 1.46.0-wmf.24
first-letter
Média
Spécial
Discussion
Utilisateur
Discussion utilisateur
Wikilivres
Discussion Wikilivres
Fichier
Discussion fichier
MediaWiki
Discussion MediaWiki
Modèle
Discussion modèle
Aide
Discussion aide
Catégorie
Discussion catégorie
Transwiki
Discussion Transwiki
Wikijunior
Discussion Wikijunior
TimedText
TimedText talk
Module
Discussion module
Event
Event talk
Philosophie/Histoire de la philosophie
0
615
764341
763991
2026-04-22T05:36:25Z
PandaMystique
119061
764341
wikitext
text/x-wiki
<!-- ═══════════════════════════════════════════════════════════════════
EN-TÊTE PRINCIPAL
═══════════════════════════════════════════════════════════════════ -->
<div style="background: linear-gradient(180deg, #2c3e50, #1a252f); border-radius: 8px; padding: 25px 30px; margin-bottom: 20px; text-align: center;">
<div style="font-size: 1.5em; font-weight: 600; color: #ffffff; letter-spacing: 0.02em; margin-bottom: 6px;">Histoire de la philosophie</div>
<div style="font-size: 0.95em; color: #a8b8c8; letter-spacing: 0.03em;">Commentaires, vocabulaires, exposés</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════
NAVIGATION PAR PÉRIODE
═══════════════════════════════════════════════════════════════════ -->
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 6px; padding: 14px 20px; margin-bottom: 25px; text-align: center; font-size: 0.9em;">
<span style="color: #666; margin-right: 8px;">Naviguer :</span>
[[#Antique|<span style="color: #8a5a30;">● Antiquité</span>]] •
[[#Moderne|<span style="color: #4a6a8a;">● Époque moderne</span>]] •
[[#Contemporaine|<span style="color: #5a3d7a;">● Contemporaine</span>]] •
[[#Bibliographie|<span style="color: #555;">● Bibliographie</span>]]
</div>
<!-- ═══════════════════════════════════════════════════════════════════
FRISE CHRONOLOGIQUE SIMPLIFIÉE
═══════════════════════════════════════════════════════════════════ -->
<table style="width: 100%; border-collapse: collapse; margin-bottom: 30px;">
<tr>
<td style="width: 25%; background: linear-gradient(180deg, #f5efe5, #ebe3d5); border: 1px solid #c9b896; border-radius: 6px 0 0 6px; padding: 12px 15px; text-align: center;">
<div style="font-size: 0.75em; color: #8a6a40; text-transform: uppercase; letter-spacing: 0.08em;">Antiquité</div>
<div style="font-size: 0.85em; color: #5a4a30; margin-top: 4px;">VIᵉ s. av. J.-C. → Vᵉ s.</div>
</td>
<td style="width: 25%; background: linear-gradient(180deg, #e8f0f5, #dae6ef); border: 1px solid #a0b8c8; padding: 12px 15px; text-align: center;">
<div style="font-size: 0.75em; color: #4a6a85; text-transform: uppercase; letter-spacing: 0.08em;">Moyen Âge</div>
<div style="font-size: 0.85em; color: #3a5065; margin-top: 4px;">Vᵉ → XVᵉ s.</div>
</td>
<td style="width: 25%; background: linear-gradient(180deg, #eef5f0, #e0ede5); border: 1px solid #7aa088; padding: 12px 15px; text-align: center;">
<div style="font-size: 0.75em; color: #4a7a5a; text-transform: uppercase; letter-spacing: 0.08em;">Époque moderne</div>
<div style="font-size: 0.85em; color: #3a5a45; margin-top: 4px;">XVIᵉ → XVIIIᵉ s.</div>
</td>
<td style="width: 25%; background: linear-gradient(180deg, #f0eaf5, #e4daf0); border: 1px solid #9080a8; border-radius: 0 6px 6px 0; padding: 12px 15px; text-align: center;">
<div style="font-size: 0.75em; color: #6a5080; text-transform: uppercase; letter-spacing: 0.08em;">Contemporaine</div>
<div style="font-size: 0.85em; color: #4a3860; margin-top: 4px;">XIXᵉ → XXIᵉ s.</div>
</td>
</tr>
</table>
<!-- ═══════════════════════════════════════════════════════════════════
SECTION : PHILOSOPHIE ANTIQUE
═══════════════════════════════════════════════════════════════════ -->
<div id="Antique" style="margin: 30px 0 15px 0; padding-bottom: 6px; border-bottom: 2px solid #c9a860;">
<span style="font-size: 1.15em; font-weight: 700; color: #6a5020; letter-spacing: 0.02em;">PHILOSOPHIE ANTIQUE</span>
<span style="font-size: 0.85em; color: #999; margin-left: 12px;">VIᵉ siècle av. J.-C. — Vᵉ siècle</span>
</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- PRÉSOCRATIQUES -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #faf6ed, #f2ebdc); border:1px solid #d4c090; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#5a4a20; margin-bottom:8px;">🌅 [[Philosophie/Présocratiques|Présocratiques]]</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Les premiers penseurs grecs cherchent le principe (''archè'') de toutes choses.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #d4c090; padding-top:8px;">
→ [[Philosophie/Thalès de Milet|Thalès de Milet]]<br/>
→ [[Philosophie/Anaximandre de Milet|Anaximandre]]<br/>
→ [[Dictionnaire de philosophie/Anaxagore|Anaxagore]]
</div>
</td>
<!-- PLATON -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #fdf8ed, #f6eedc); border:1px solid #d4b860; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#5a4800; margin-bottom:8px;">📜 [[Pour lire Platon|Platon]]</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Théorie des Idées, dialectique et fondation de l'Académie.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #d4b860; padding-top:8px;">
→ [[Pour lire Platon/Guide des dialogues/Apologie de Socrate|Apologie de Socrate]]<br/>
→ [[Pour lire Platon/Guide des dialogues/Ion|Ion]]<br/>
→ [[Pour lire Platon/Vocabulaire|Vocabulaire platonicien]]
</div>
</td>
<!-- STOÏCIENS -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f8f4e8, #f0e8d8); border:1px solid #c8b070; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#5a4820; margin-bottom:8px;">🏛️ Stoïcisme</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Vivre selon la nature, maîtriser ses passions, accepter le destin.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #c8b070; padding-top:8px;">
→ [[Les Stoïciens : Épictète Le poignard à la main|Épictète]]
</div>
</td>
</tr>
</table>
<!-- ═══════════════════════════════════════════════════════════════════
SECTION : PHILOSOPHIE MODERNE
═══════════════════════════════════════════════════════════════════ -->
<div id="Moderne" style="margin: 35px 0 15px 0; padding-bottom: 6px; border-bottom: 2px solid #4a90b8;">
<span style="font-size: 1.15em; font-weight: 700; color: #2a5a7a; letter-spacing: 0.02em;">PHILOSOPHIE MODERNE</span>
<span style="font-size: 0.85em; color: #999; margin-left: 12px;">XVIᵉ — XVIIIᵉ siècle</span>
</div>
<!-- Sous-section : XVIIe siècle -->
<div style="font-size: 0.9em; font-weight: 600; color: #4a6a85; margin: 20px 0 12px 0; padding-left: 10px; border-left: 3px solid #a0c0d8;">XVIIᵉ siècle — L'âge classique</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- DESCARTES -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #eef4f8, #e0ecf4); border:1px solid #6090b8; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#1a4a6a; margin-bottom:4px;">[[Dictionnaire de philosophie/René Descartes|René Descartes]]</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1596 — 1650</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Le ''cogito'', le doute méthodique et la fondation de la philosophie moderne.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #6090b8; padding-top:8px;">
→ [[Méditations métaphysiques]]
</div>
</td>
<!-- SPINOZA -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #edf5f2, #dfeee8); border:1px solid #5a9878; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#1a5038; margin-bottom:4px;">Baruch Spinoza</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1632 — 1677</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Substance unique, déterminisme et béatitude par la connaissance.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #5a9878; padding-top:8px;">
→ [[Commentaire de l'Éthique]]
</div>
</td>
<!-- PASCAL -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f5f0f8, #ebe4f2); border:1px solid #8878a8; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#3a2860; margin-bottom:4px;">Blaise Pascal</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1623 — 1662</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Misère et grandeur de l'homme, le pari, la condition humaine.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #8878a8; padding-top:8px;">
→ [[Philosophie/Commentaire du passage à propos de l'Homme esclave du divertissement|Le divertissement]]<br/>
→ [[Philosophie/Commentaire du passage à propos des deux infinis|Les deux infinis]]
</div>
</td>
</tr>
</table>
<!-- Sous-section : XVIIIe siècle -->
<div style="font-size: 0.9em; font-weight: 600; color: #4a6a85; margin: 25px 0 12px 0; padding-left: 10px; border-left: 3px solid #a0c0d8;">XVIIIᵉ siècle — Les Lumières</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- HUME -->
<td style="width:50%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f0f5f8, #e2eef5); border:1px solid #5088b0; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#1a4a68; margin-bottom:4px;">David Hume</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1711 — 1776</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Empirisme radical, critique de la causalité et scepticisme modéré.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #5088b0; padding-top:8px;">
→ [[Philosophie/Vocabulaire/David Hume|Vocabulaire]]
</div>
</td>
<!-- KANT -->
<td style="width:50%; vertical-align:top; position:relative; background:linear-gradient(180deg, #eef2f8, #e0e8f2); border:1px solid #6080a8; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#2a3860; margin-bottom:4px;">Emmanuel Kant</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1724 — 1804</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Révolution copernicienne, critique de la raison et impératif catégorique.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #6080a8; padding-top:8px;">
→ [[Philosophie/Vocabulaire/Kant|Vocabulaire]]<br/>
→ [[Commentaire de la Fondation de la métaphysique des mœurs|Fondation de la métaphysique des mœurs]]
</div>
</td>
</tr>
</table>
<!-- ═══════════════════════════════════════════════════════════════════
SECTION : PHILOSOPHIE CONTEMPORAINE
═══════════════════════════════════════════════════════════════════ -->
<div id="Contemporaine" style="margin: 35px 0 15px 0; padding-bottom: 6px; border-bottom: 2px solid #9070b0;">
<span style="font-size: 1.15em; font-weight: 700; color: #5a3d7a; letter-spacing: 0.02em;">PHILOSOPHIE CONTEMPORAINE</span>
<span style="font-size: 0.85em; color: #999; margin-left: 12px;">XIXᵉ — XXIᵉ siècle</span>
</div>
<!-- Sous-section : XIXe siècle -->
<div style="font-size: 0.9em; font-weight: 600; color: #6a5080; margin: 20px 0 12px 0; padding-left: 10px; border-left: 3px solid #c0a8d0;">XIXᵉ siècle</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- NIETZSCHE -->
<td style="width:50%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f8f0f2, #f0e4e8); border:1px solid #a87080; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#5a2838; margin-bottom:4px;">[[Philosophie/Nietzsche|Friedrich Nietzsche]]</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1844 — 1900</div>
<div style="font-size:0.88em; color:#555; line-height:1.6;">Critique de la morale, volonté de puissance, mort de Dieu et éternel retour.</div>
</td>
<!-- Placeholder pour futurs philosophes du XIXe -->
<td style="width:50%; vertical-align:top; background: #fafafa; border: 1px dashed #ccc; border-radius:8px; padding:16px 18px; color: #999; font-size: 0.9em; text-align: center;">
<div style="margin: 15px 0;">''À venir : Hegel, Marx, Kierkegaard…''</div>
</td>
</tr>
</table>
<!-- Sous-section : XXe siècle -->
<div style="font-size: 0.9em; font-weight: 600; color: #6a5080; margin: 25px 0 12px 0; padding-left: 10px; border-left: 3px solid #c0a8d0;">XXᵉ siècle</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- HEIDEGGER -->
<td style="width:50%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f3eef8, #e8e0f2); border:1px solid #8068a0; border-radius:8px; padding:16px 18px; overflow:hidden;">
<div style="font-weight:bold; font-size:1.05em; color:#3a2858; margin-bottom:4px;">Martin Heidegger</div>
<div style="font-size:0.8em; color:#888; margin-bottom:8px;">1889 — 1976</div>
<div style="font-size:0.88em; color:#555; line-height:1.6; margin-bottom:10px;">Question de l'être, ''Dasein'', temporalité et critique de la métaphysique.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #8068a0; padding-top:8px;">
→ [[Être et Temps]]
</div>
</td>
<!-- Placeholder pour futurs philosophes du XXe -->
<td style="width:50%; vertical-align:top; background: #fafafa; border: 1px dashed #ccc; border-radius:8px; padding:16px 18px; color: #999; font-size: 0.9em; text-align: center;">
<div style="margin: 15px 0;">''À venir : Sartre, Merleau-Ponty, Wittgenstein…''</div>
</td>
</tr>
</table>
<!-- Sous-section : Courants -->
<div style="font-size: 0.9em; font-weight: 600; color: #6a5080; margin: 25px 0 12px 0; padding-left: 10px; border-left: 3px solid #c0a8d0;">Courants philosophiques</div>
<table style="width:100%; border-collapse:separate; border-spacing:12px;">
<tr>
<!-- PHILOSOPHIE ANALYTIQUE -->
<td style="width:33%; vertical-align:top; position:relative; background:linear-gradient(180deg, #f0f2f8, #e5e8f2); border:1px solid #7080a0; border-radius:8px; padding:14px 16px; overflow:hidden;">
<div style="font-weight:bold; font-size:1em; color:#2a3860; margin-bottom:6px;">🔬 [[Philosophie analytique]]</div>
<div style="font-size:0.85em; color:#555; line-height:1.5; margin-bottom:10px;">Analyse logique du langage et clarification des concepts.</div>
<div style="font-size:0.85em; color:#666; border-top:1px dashed #8068a0; padding-top:8px;">
→ [[Ignorance: A Case for Scepticism]]
</div>
</td>
<!-- Placeholders pour futurs courants -->
<td style="width:33%; vertical-align:top; background: #fafafa; border: 1px dashed #ccc; border-radius:8px; padding:14px 16px; color: #999; font-size: 0.85em; text-align: center;">
''À venir : Phénoménologie''
</td>
<td style="width:33%; vertical-align:top; background: #fafafa; border: 1px dashed #ccc; border-radius:8px; padding:14px 16px; color: #999; font-size: 0.85em; text-align: center;">
''À venir : Existentialisme''
</td>
</tr>
</table>
<!-- ═══════════════════════════════════════════════════════════════════
SECTION : BIBLIOGRAPHIE
═══════════════════════════════════════════════════════════════════ -->
<div id="Bibliographie" style="margin: 35px 0 15px 0; padding-bottom: 6px; border-bottom: 2px solid #888;">
<span style="font-size: 1.15em; font-weight: 700; color: #444; letter-spacing: 0.02em;">BIBLIOGRAPHIE</span>
<span style="font-size: 0.85em; color: #999; margin-left: 12px;">Ouvrages de référence</span>
</div>
<div style="background: linear-gradient(180deg, #fafafa, #f5f5f5); border: 1px solid #e0e0e0; border-radius: 8px; padding: 18px 22px; font-size: 0.92em; line-height: 1.8; color: #444;">
<div style="margin-bottom: 8px;">📚 <strong>PRADEAU</strong>, Jean-François (dir.), ''Histoire de la philosophie'', Éditions du Seuil, 2009</div>
<div style="margin-bottom: 8px;">📚 <strong>CHÂTELET</strong>, François, ''Histoire de la philosophie'', 8 tomes, Paris, Hachette-Pluriel, 1999-2000</div>
<div style="margin-bottom: 8px;">📚 <strong>BRÉHIER</strong>, Émile, ''Histoire de la philosophie'', PUF, Quadrige, 2004, {{ISBN|2-13054-396-0}} — [http://classiques.uqac.ca/classiques/brehier_emile/brehier_emile.html Texte en ligne]</div>
<div>📚 <strong>ZARADER</strong>, Jean-Pierre (dir.), ''Le vocabulaire des philosophes'', 5 tomes, Paris, Ellipses, 2002-2006</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════
FOOTER : RESSOURCES
═══════════════════════════════════════════════════════════════════ -->
<div style="margin-top: 25px; background: linear-gradient(180deg, #f5f5f3, #eaeae8); border: 1px solid #d8d8d5; border-radius: 8px; padding: 16px 20px;">
<div style="font-size: 0.8em; font-weight: 700; color: #555; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 10px;">Voir aussi</div>
<div style="font-size: 0.9em; color: #444; line-height: 1.7;">
→ [[Philosophie|Portail Philosophie]] •
→ [[Dictionnaire de philosophie|Dictionnaire des concepts]] •
→ [[Manuel de terminale de philosophie|Manuel de Terminale]] •
→ [[w:Histoire de la philosophie|Wikipédia]]
</div>
</div>
[[Catégorie:Discipline philosophique]]
[[Catégorie:Histoire|Histoire de la philosophie]]
[[Catégorie:Histoire de la philosophie|*]]
e1qg9wongit55qg3m8y68sgncyq9u4j
Pour lire Platon/Guide des dialogues/Ion
0
29697
764266
642552
2026-04-21T20:21:33Z
PandaMystique
119061
764266
wikitext
text/x-wiki
== Introduction générale ==
=== Statut et datation du dialogue ===
{{wikisource|Ion (Platon)|Ion}}
L{{'}}''Ion'' est l'un des plus brefs dialogues du corpus platonicien, une douzaine de pages Stephanus (530a-542b) pour une conversation dont la durée fictive n'excède pas la demi-heure entre Socrate et le rapsode Ion d'Éphèse. Cette brièveté, jointe au caractère apparemment simpliste d'Ion comme interlocuteur, a longtemps nourri un soupçon d'inauthenticité ou de légèreté. Goethe voyait dans le dialogue « ''nichts als eine Persiflage'' » (« rien qu'une parodie »), et plusieurs philologues, Wilamowitz en tête, ont douté qu'il fût de Platon, avant que Wilamowitz lui-même, vers la fin de sa carrière, ne revienne partiellement sur son jugement. L'authenticité est aujourd'hui largement admise, sans être absolument consensuelle.
La datation reste débattue. Traditionnellement rangé parmi les dialogues de jeunesse, voire parmi les premiers écrits platoniciens,, l{{'}}''Ion'' a été rapproché par Albert Rijksbaron de la période où Platon rédigeait la ''République'' et le ''Phèdre'', sur la base d'un vocabulaire technique et de procédures argumentatives communs à ces œuvres. Cette thèse n'est pas universellement acceptée : plusieurs commentateurs maintiennent une date plus précoce, et les critères stylométriques sont ici peu concluants, comme le rappelle Aguirre.
La date dramatique fictive se laisse conjecturer à partir d'indices internes : Ion revient d'Épidaure, où il vient de remporter les concours rapsodiques des fêtes d'Asclépios, et attend les Grandes Panathénées à Athènes. La conversation se placerait donc vraisemblablement, mais sans certitude, dans la période précédant ces Panathénées, dont la journée principale tombait le 28 Hécatombéon. Rijksbaron note d'ailleurs que, si l'on accepte cette reconstruction, Ion aurait passé plusieurs semaines désœuvré à Athènes, ce qui n'est pas sans poser question.
=== Les deux personnages ===
Socrate apparaît ici tel qu'on le connaît : ironique, réservé, méthodique, se disant ''idiôtês'' (profane, 532d9) face aux « sages ». Il refuse d'emblée la qualification de ''sophos'' qu'Ion lui attribue (532d) et la renvoie, non sans malice, aux rapsodes, acteurs et poètes eux-mêmes.
Ion d'Éphèse est un rapsode présenté comme célèbre, mais son historicité reste incertaine : aucune source indépendante ne le mentionne, et il est possible qu'il s'agisse d'un personnage fictif. Le portrait qu'en donne le dialogue correspond en tout cas, dans ses grandes lignes, au type social du rapsode professionnel tel qu'on peut le reconstituer pour l'époque classique : tournée de concours, prestations en tenue somptueuse avec couronne d'or, rémunération substantielle, prétention à être non seulement récitant mais ''hermêneus'' (interprète) de la pensée du poète, et ambition de se poser en éducateur au titre de spécialiste d'Homère. Il ne faut toutefois pas confondre le temps dramatique du dialogue, le temps de Platon écrivant, et les pratiques attestées de la rhapsodie : le texte est un portrait littéraire, construit pour les besoins de l'argument, avant d'être un document historique sur les rhapsodes.
Par ce personnage, Platon vise un ensemble : l'héritier de l'aède, qui a renoncé à la cithare mais garde le ''rhabdos'' (bâton), et qui porte la culture épique dans les festivals publics. Cette figure condense, aux yeux de Platon, le système éducatif traditionnel fondé sur la mémorisation et l'interprétation des poèmes homériques.
=== Structure générale et enjeu ===
Le dialogue s'articule en trois grandes sections organisées autour d'un noyau central :
* Partie I (530a-533c) : dialogue dialectique qui met en question la possibilité, pour Ion, de posséder une ''technê'' rhapsodique au sens strict, puisqu'il prétend n'être expert que d'Homère alors que la poésie, ''si'' elle est une ''technê'', constitue un tout.
* Partie II (533c-536d) : long développement de Socrate où la notion de ''technê'' est remplacée par celle d{{'}}''enthousiasmos'', une puissance divine (''theia dynamis'') qui fait du poète et du rapsode les maillons d'une chaîne magnétique partant de la Muse.
* Partie III (536d-541e) : retour à l'examen de la ''technê'' par l'analyse de passages homériques concrets, aboutissant au dilemme final.
* Épilogue (541e-542b) : alternative entre deux statuts qu'Ion peut revendiquer, injuste (s'il possède une ''technê'' qu'il refuse de montrer) ou divin (s'il n'en a pas).
La question du sens global du dialogue reste discutée. Une lecture forte, répandue chez les commentateurs modernes (Rijksbaron, Aguirre, von der Walde notamment), y voit un geste de disqualification de la poésie traditionnelle comme savoir et comme modèle éducatif du citoyen grec. Dans cette perspective, l{{'}}''Ion'' préparerait déjà les thèses du livre X de la ''République''. Une autre lecture, défendue notamment par Penelope Murray et reprise, avec des nuances, par Grace Ledbetter ou Suzanne Stern-Gillet, insiste davantage sur l'instabilité du texte : Socrate mobiliserait la doctrine de l'inspiration sans nécessairement l'endosser de façon simple, et le dialogue serait plus suggestif que conclusif. Le commentaire qui suit privilégie, par commodité d'exposition, la première ligne, tout en signalant, aux moments décisifs, les points où l'autre lecture peut légitimement se faire entendre.
== I. Le prologue (530a-531a) : la mise en place ==
=== 530a-b : les salutations et le contexte ===
Le dialogue s'ouvre sur une formule de salutation étonnamment solennelle : « Τὸν Ἴωνα χαίρειν », le nom propre à l'accusatif, précédé de l'article, suivi du verbe à l'infinitif. Ce n'est pas l'habituel « ὦ Ἴων » que Socrate utilise avec ses proches ; c'est une formule de déférence, presque protocolaire, qui présente Ion comme un personnage illustre. On peut y entendre, rétrospectivement, une charge ironique : la suite confirme que Socrate ne partage pas, en réalité, l'estime que suggère ce salut.
Les salutations révèlent que les deux hommes se connaissent déjà : Socrate sait qu'Ion est Éphésien, connaît son activité et le motif de son séjour à Athènes. L'échange initial, avec son ''hêmin'' (« nous ») qui feint la camaraderie, crée une connivence qui se dissipera à mesure que Socrate reprendra ses distances.
Ion vient de remporter « les premiers prix » à Épidaure, lors des concours rapsodiques associés aux fêtes d'Asclépios, et espère vaincre également aux Panathénées athéniennes, les deux plus importants festivals rapsodiques du monde grec. Cette double mention établit le prestige d'Ion ; elle peut aussi, plus discrètement, poser la question de la valeur réelle d'une couronne remportée dans de telles compétitions. La vie itinérante du rapsode, toujours en voyage d'un concours à l'autre, est un trait qui le rapproche du mode de vie des sophistes, et contraste avec l'enracinement athénien de Socrate (qui n'a quitté Athènes que pour trois campagnes militaires).
=== 530b-c : la double dimension du rapsode ===
Socrate enchaîne sur un éloge du rapsode qui pose, en réalité, les termes conceptuels de la discussion à venir. Trois motifs se détachent :
# L'apparence (''kekosmêsthai'') : le rapsode se présente dans une tenue somptueuse qui convient à son art. Cet aspect physique reviendra à plusieurs reprises (535d, 541c) et sera tourné en dérision.
# La fréquentation des poètes : le rapsode est nécessairement en contact avec les plus grands, « en particulier avec Homère, le meilleur et le plus divin (''theiotatos'') de tous ». Le qualificatif ''theiotatos'' appliqué à Homère est suggestif : il prépare la terminologie qui structurera la conclusion du dialogue, où « divin » sera opposé à « technicien ».
# L'exigence herméneutique : le rapsode ne doit pas seulement mémoriser les vers (''ta epê'') mais en saisir la pensée (''dianoia'') : « il ne serait pas un bon rapsode s'il ne comprenait pas ce que dit le poète » (530b-c). Cette phrase installe le cadre épistémique dans lequel Socrate va conduire l'examen : ''epê'' d'un côté, ''dianoia'' de l'autre, mots et pensée.
Le vocabulaire cognitif est dense : ''syniénai, gignôskein, epistasthai, phrontizein, krinein, eidenai'', toute une constellation qui amène insensiblement la rhapsodie sur le terrain du savoir.
Socrate introduit alors le concept-clef de la première partie : le rapsode est ''hermêneus'', interprète, médiateur, de la pensée du poète auprès des auditeurs (530c). Le terme va jouer un rôle double dans le dialogue :
* d'abord comme interprète au sens herméneutique (celui qui ''explique'' le texte) ;
* puis, dans la partie centrale, comme simple intermédiaire par lequel passe une parole qui ne lui appartient pas.
=== 530c-531a : Ion se vante ===
Ion, ravi, confirme et surenchérit. Il a, dit-il, mis tout son soin à comprendre la pensée d'Homère et « parle mieux que quiconque » à son sujet. Il se dit digne de recevoir la couronne d'or des Homérides. La vanité d'Ion apparaît dans sa forme la plus directe, mais pas caricaturale : c'est celle d'un professionnel persuadé de la valeur de son métier.
Socrate propose alors la première esquive : il réclame un entretien préalable à toute ''epideixis'' (exhibition publique), stratégie qu'il emploiera à plusieurs reprises pour empêcher Ion de se dérober dans la performance (531a, 536d, 538d).
Socrate pose alors la question qui va déclencher toute l'argumentation : « Es-tu expert seulement sur Homère, ou bien aussi sur Hésiode et Archiloque ? » Ion, dans ce que Sales et Menza ont appelé, respectivement, « le motif possibilisateur du dialogue » et la « proposition catalysante », répond fièrement : « Nullement, mais seulement sur Homère, car cela me suffit ».
Cette réponse est l'étincelle. Si Ion affirme être excellent sur Homère ''et seulement'' sur Homère, une question devient inévitable : comment cela est-il possible, dès lors qu'Homère parle des mêmes thèmes que les autres poètes ? La tension entre la prétention universelle de la compétence homérique et sa restriction à Homère seul va fournir le levier de toute la première réfutation.
== II. Première partie (531a-533c) : l'argument du ''tout'' ==
=== 531a-d : le problème des sujets communs ===
Socrate commence par une question apparemment innocente : Homère et Hésiode parlent-ils des mêmes choses ? Oui, répond Ion, sur beaucoup de sujets. Sur ces sujets communs, donc, Ion explique-t-il aussi bien Hésiode qu'Homère ? Oui, concède-t-il, au moins sur ce qu'ils disent de la même manière. Quant aux sujets où ils divergent, par exemple la mantique (où Homère et Hésiode disent « quelque chose »), c'est un devin qui jugera le mieux, non Ion.
Socrate déploie alors un premier mouvement décisif (531b-c). Si quelqu'un est devin au point de pouvoir expliquer ce que les poètes disent de la même manière, il doit aussi être capable d'expliquer ce qu'ils disent différemment. La compétence d'expert porterait donc sur la ''matière'' et non sur l'auteur. Un expert en mantique juge ''toute'' énonciation mantique, d'où qu'elle vienne ; il ne saurait être expert des énoncés divinatoires d'Homère seul et ignorant de ceux d'Hésiode.
Socrate élargit alors la gamme des sujets qu'Homère traite (531c-d) : la guerre, les relations humaines (entre bons et méchants, profanes et spécialistes), les rapports entre dieux et hommes, les événements célestes et infernaux, la généalogie des dieux et des héros. L'éventail est quasi encyclopédique, et c'est précisément cette prétention à l'universalité des contenus poétiques qui permet à Socrate de la retourner.
Les autres poètes n'ont-ils pas traité les mêmes sujets ? Ion concède qu'ils l'ont fait, mais « bien moins bien qu'Homère ». Cette concession est décisive : Ion admet implicitement qu'il existe un critère de qualité, donc une norme selon laquelle juger.
=== 531d-532b : le critère unique de jugement ===
Socrate introduit alors le principe fondamental : celui qui reconnaît qui parle ''bien'' sur un sujet reconnaît aussi qui parle ''mal''. Si plusieurs personnes parlent de nombres, celui qui reconnaîtra l'expert reconnaîtra aussi le médiocre, c'est l'arithméticien. Si plusieurs parlent d'aliments sains, c'est le médecin qui départagera. Un expert juge donc à la fois le bon et le mauvais dans son domaine.
Application (532b) : puisqu'Ion dit qu'Homère et les autres poètes traitent des mêmes sujets, et puisque le bon juge reconnaît tant l'excellent que le moins bon, Ion, s'il est vraiment expert, devrait être « juge compétent » (''kritês hikanos'') de tous les poètes, non d'Homère seul.
Ion sent le piège, « il semblerait » (''éoiken ge''), répond-il, avec réticence, mais accepte la conclusion tout en maintenant son exclusivité homérique. La contradiction est désormais pleinement formulée : Ion prétend posséder une compétence à prétention universelle (il peut juger tout ce que dit Homère, qui parle de tout) tout en confessant une incompétence universelle sur les autres poètes qui parlent des mêmes choses.
=== 532c-533c : le principe de totalité de la ''technê'' ===
Socrate formule alors le principe méthodologique central : toute ''technê'' est un ''tout'' (''holon''). Il est remarquable qu'il introduise ici la ''technê'' poétique avec un prudent ''pou'' (« je suppose ») : « ποιητικὴ γάρ πού ἐστιν τὸ ὅλον » (532c7-8), « car il y a, je suppose, un art poétique comme un tout ». Ce ''pou'' n'est pas anodin. Rijksbaron, suivi par d'autres, estime que la ''technê'' poétique n'est introduite ici qu{{'}}''argumenti causa'', pour les besoins de la démonstration, sans que Platon lui reconnaisse d'existence effective. Cette lecture est cohérente avec l'ensemble du dialogue et elle est commune aujourd'hui, mais on peut aussi, plus prudemment, y voir une simple réserve rhétorique.
Socrate multiplie alors les exemples de ''technai'' réelles où le principe s'applique :
* La peinture (532e-533a) : existe-t-il quelqu'un d'expert sur Polygnote seul, capable d'expliquer ses réussites et ses échecs, mais qui reste « sans voix, endormi et sans rien à dire » devant les autres peintres ? Non, bien sûr.
* La sculpture (533b) : même démonstration avec Dédale de Métion, Épeios de Panopée, Théodore de Samos.
* La musique, flûte, cithare, chant à la cithare (533b-c) : même principe ; personne n'est expert d'Olympos ou de Thamyras seulement.
* La rhapsodie elle-même (533c) : personne n'est expert de Phémios (le rapsode ithacien de l{{'}}''Odyssée'') seul et incapable de juger Ion d'Éphèse.
Chaque exemple renvoie à des figures réelles, mythiques ou historiques, et évoque un domaine entier où le principe est évidemment valide. Socrate souligne qu'« il importe peu que l'on prenne ''telle ou telle'' ''technê'' comme illustration : la même méthode d'examen vaudra pour toutes les ''technai'' » (532d-e).
La conclusion de ce mouvement est la suivante : si la poésie était une ''technê'', son expert serait capable de juger tous les poètes également. Or Ion ne peut parler bien que d'Homère. Donc, ou bien la poésie n'est pas une ''technê'', ou bien Ion n'est pas un expert. En prenant la ''poiêtikê'' comme tout, Socrate tend à unir, dans un même objet d'analyse, composition (le poète) et interprétation (le rapsode). L'examen dialectique paraît englober toute la chaîne.
=== 533c : l'aveu d'Ion et la demande d'explication ===
Ion, rendu perplexe (« je ne peux te contredire sur ce point »), revient cependant à sa conviction : « Je suis conscient que sur Homère je parle mieux que quiconque… et tous les autres disent que je parle bien. Mais regarde ce que cela signifie ». Cette demande d'éclaircissement marque la transition vers la partie centrale.
Socrate n'insiste pas sur la réfutation dialectique. Il offre à Ion une forme de consolation, dont le statut est précisément l'un des points les plus débattus du dialogue : si l'on suit Rijksbaron ou Aguirre, c'est une consolation empoisonnée, une apparente promotion qui se révèle être, au fil du développement, une disqualification ; si l'on suit Murray ou Stern-Gillet, la doctrine que Socrate va développer peut être prise plus au sérieux qu'on ne le dit, ou à tout le moins comporter une ambivalence. La question mérite d'être posée dès ce seuil, car elle engage la lecture de toute la section centrale.
== III. Partie centrale (533c-536d) : l{{'}}''enthousiasmos'' et la chaîne magnétique ==
=== 533c-534e : la métaphore de la pierre magnétique ===
Socrate annonce : « Je vais te montrer de quoi il s'agit » (''erchomai ge soi apophanoumenos''). Ce qui permet à Ion de bien parler d'Homère ne serait pas une ''technê'' mais une « puissance divine » (''theia dynamis'', 533d3). Socrate développe alors l'une des métaphores les plus célèbres de l'œuvre platonicienne.
La pierre qu'Euripide appelait « Magnésienne » (fragment 571 Nauck, tiré de l{{'}}''Oineus'') et que la plupart appellent « Héraclée », la pierre aimantée, non seulement attire les anneaux de fer, mais leur transmet sa propre force d'attraction, si bien qu'ils peuvent à leur tour attirer d'autres anneaux, formant une chaîne. De même la Muse, directement (''autê'', « par elle-même », et non par quelque intermédiaire technique), rend les poètes ''entheoi'' (« inspirés », littéralement « qui ont le dieu en eux ») et, à travers ces inspirés, fait de toute une ligne d'autres personnes des ''enthousiazontes''.
Le passage est d'une grande densité sémantique. Les verbes ''artaô, anartaô, exartaô'' (« pendre, être suspendu ») disent la dépendance du poète à l'égard de la source divine. La syntaxe elle-même, comme le suggère Omert Schrier (cité par Rijksbaron), adopte un rythme qui imite presque iconiquement le frémissement corybantique. Il existe enfin une distinction sémantique fine, mais significative, entre ''entheoi'' (les poètes, qui ''ont'' le dieu en eux) et ''enthousiazontes'' (les rapsodes et spectateurs, que l'inspiration reçue par transmission met en mouvement).
La description, si on la prend à la lettre, rompt avec une part importante de la tradition poétique grecque. Comme le souligne von der Walde, les poètes archaïques, Homère, Hésiode, Pindare, ne se présentent pas, dans leurs propres textes, comme passifs et possédés. L'invocation aux Muses chez Homère (''Iliade'' II, 480-492) ou Hésiode (''Théogonie'' 104-115) n'implique pas, à première vue, extase ou perte de conscience. C'est Platon qui, dans l{{'}}''Ion'', les ''Lois'' (719c) et le ''Phèdre'', articule fortement l'image du poète à la figure du ''mainomenos'' (fou), du ''mantis'' en transe, de la Pythie sur son trépied. Le « ''palaios mythos'' » dont parlent les ''Lois'' est, selon plusieurs interprètes, plus une reconstruction platonicienne qu'une tradition ancienne attestable. Reste que d'autres sources archaïques (certains hymnes, certains fragments lyriques) peuvent être lues dans le sens d'une continuité partielle : le dossier n'est pas entièrement à sens unique.
=== 534a-b : poètes lyriques, corybantes, bacchantes ===
Socrate élargit l'analyse aux poètes lyriques (''melopoioi''). Ceux-ci ne composeraient pas leurs beaux vers quand ils sont ''emphrones'' (dans leur bon sens), mais seulement quand ils sont « entrés dans l'harmonie et dans le rythme ». Les comparaisons s'accumulent : les corybantes ne dansent pas quand ils sont dans leur bon sens, les bacchantes ne tirent du miel et du lait des fleuves que quand elles sont possédées.
Le jeu phonétique est savant : ''melopoioi'' (534a1, a6) résonne avec ''melê'' (chants, 534a2), ''meli'' (miel, 534a5) et ''melirryton'' (qui coule comme du miel, 534b1). Le tissage sonore renforce l'analogie et tend à dissoudre les frontières conceptuelles entre poètes, corybantes et bacchantes.
Socrate livre alors l'une des définitions les plus fameuses de l{{'}}''Ion'' : le poète est « chose légère, ailée et sacrée » (''kouphon… ptênon… hieron''), « incapable de composer avant d'être inspiré, hors de lui et qu'en lui il n'y ait plus de raison » (534b). La métaphore de l'abeille, commune dans la tradition poétique grecque (Pindare, Bacchylide, Callimaque, Euripide), est reprise : le poète butine les sources et les jardins des Muses, ce qui évoque simultanément la douceur du chant et la dépossession, ''kouphon'' peut aussi signifier « vide ». Les ailes et le vol rapprochent le poète du chamane. Toute cette imagerie oriente vers l'idée que l'activité poétique ne résulterait pas d'un savoir, mais d'un don divin exceptionnel et transitoire. Le verdict est posé en 534c1 et répété en 535a4 : c'est par ''theia moira'' (« allotissement divin ») que les poètes font ce qu'ils font, ''ou technêi'' (« non par art »).
On notera la quasi-équivalence, dans ce passage, des termes ''theia dynamis'' (533d3), ''theia moira'' (534c1, 535a4), ''katokochê'' (« possession », 533e7) et ''enthousiasmos'' (533e5, 535c2, 536b3). Platon accumule les expressions synonymes pour souligner le caractère non rationnel de l'activité poétique, ce qui ne préjuge pas encore de la valeur finale qu'il accorde à cette inspiration.
=== 534c-535a : les exemples confirmants ===
Socrate illustre alors son propos par trois considérations :
# Spécialisation des inspirations : chaque poète n'est capable de bien composer que dans le genre où la Muse l'a poussé, dithyrambes, encomiums, hyporchèmes, épopées, iambes. « Dans les autres genres, il est nul ». La diversité des talents poétiques trahirait ainsi leur origine divine : si c'était une ''technê'', un poète devrait pouvoir exceller en tous genres.
# Tynnichos de Chalcis (534d) : preuve la plus belle, dit Socrate. Ce poète par ailleurs médiocre (''phaulotatos poiêtês'') a composé un péan en l'honneur d'Apollon que tout le monde chante encore et qui est « presque la plus belle de toutes les chansons ». Il le disait lui-même : « une invention des Muses ». Le cas illustrerait que le dieu parle à travers les poètes, comme l'oracle, précisément pour que les hommes sachent que ces beaux poèmes ne sont pas humains (''ouk anthrôpina''), mais divins (''theia''), les poètes n'étant que des ''hermêneis tôn theôn'' (« interprètes des dieux »), chacun possédé par le dieu qui l'a pris. On observe ici que le terme ''hermêneus'' s'est déjà déplacé par rapport à l'usage initial (530c) : il ne désigne plus celui qui ''explique'' le texte, mais celui qui ''transmet passivement'' le message divin.
# L'unicité rhapsodique d'Ion : c'est pour cette raison que le dieu, par dessein, chanterait les plus beaux vers à travers le poète le plus médiocre, pour que nul n'attribue les œuvres divines à un talent proprement humain.
Ion, à ce point, avoue être « touché » par les paroles de Socrate (535a2). Il concède : « Les bons poètes nous transmettent par ''theia moira'' ces choses qui viennent des dieux ». Et quand Socrate lui demande si les rapsodes ne sont pas, eux aussi, les interprètes des poètes, Ion acquiesce. La formule qu'il accepte a un poids considérable : les rapsodes sont « ἑρμηνέων ἑρμηνῆς » (535a8), « des interprètes d'interprètes ». Selon la lecture qu'on retient, cette formule peut marquer soit l'effondrement de la position d'Ion (il ne serait plus qu'un maillon passif dans une chaîne d'ignorance transitoire), soit, de façon plus ambivalente, l'indication que l'activité rhapsodique trouve son sens ailleurs que dans la possession d'une ''technê'', sans être pour autant insignifiante. Penelope Murray, par exemple, tient que le passage central a une tonalité partiellement « élogieuse » (''eulogistic''), même s'il retire aux poètes la ''technê'' traditionnellement reconnue.
=== 535b-d : l'état mental du rapsode ===
Socrate pose alors la question : quand Ion récite Homère, Ulysse sautant sur le seuil, Achille s'élançant contre Hector, les lamentations d'Andromaque, d'Hécube, de Priam, est-il ''dans son bon sens'' (''emphrôn'') ou ''hors de lui'' (''exô heautou''), son âme s'imaginant dans les événements qu'il narre ?
Ion avoue sans détour : « Quand je récite quelque chose de pitoyable, mes yeux se remplissent de larmes ; quand c'est effrayant ou terrible, mes cheveux se dressent et mon cœur palpite ». Cette description recoupe ce que Gorgias avait décrit dans l{{'}}''Éloge d'Hélène'' (§9), et elle n'est pas très éloignée, dans la lettre, de ce qu'Aristote nommera plus tard ''catharsis'' par ''eleos'' et ''phobos'', même si Platon et Aristote évaluent ces mêmes phénomènes de manière diamétralement opposée.
Socrate pousse alors l'argument (535d) : peut-on être ''emphrôn'' quand, orné d'une étoffe bariolée et de couronnes d'or, on pleure pendant des sacrifices et des fêtes solennelles sans rien avoir perdu, ou qu'on a peur au milieu de ''vingt mille personnes'' (''dismyrioi'', chiffre peut-être hyperbolique) qui ne sont pas du tout hostiles ? La disproportion entre la situation objective (spectacle avec couronne d'or) et la réaction affective (larmes, tremblements) tend à montrer que le rapsode est ''ekphrôn'', hors de sa raison.
=== 535d-536d : le spectateur, dernier anneau ===
Socrate montre ensuite que l'état du rapsode se transmet aux spectateurs. Ion le confirme : « Je les vois, du haut de l'estrade, pleurant et me regardant terrifiés, stupéfaits de ce que j'énonce… Car il faut que je leur prête grande attention : s'ils pleurent, je rirai en touchant l'argent ; s'ils rient, c'est moi qui pleurerai pour l'argent perdu ». Le mercantilisme avoué d'Ion, qui rappelle l{{'}}''Hippias Majeur'' 282b-283b et constitue, aux yeux de Platon, un trait commun aux rapsodes et aux sophistes, n'arrange pas sa position. Surtout, Ion décrit l'effet de contagion affective qu'il produit.
Socrate peut alors donner sa forme finale à la métaphore (535e-536a) :
{| class="wikitable"
! Anneau !! Occupant
|-
| Premier anneau || Le poète (Homère)
|-
| Anneau intermédiaire || Le rapsode-acteur (Ion)
|-
| Dernier anneau || Le spectateur
|}
La divinité, à travers tous, « attire l'âme des hommes là où elle veut ». Chaque dieu suscite une chaîne propre : Orphée attire les uns, Musée les autres, Homère la plupart. Ion est possédé par Homère, ce qui expliquerait pourquoi il ne peut bien parler que de lui, et reste « sans voix » devant les autres poètes (536b-c). Même les corybantes ne sont sensibles qu'à la mélodie du dieu qui les possède.
La conclusion, en 536c-d, est nette : « Ce n'est pas par une ''technê'', mais par ''theia moira'' que tu es un formidable louangeur d'Homère ». Ion ne serait donc pas un technicien de la poésie. Que cela constitue, comme le pense la tradition interprétative majoritaire, une disqualification radicale, ou comme d'autres le soutiennent, une caractérisation plus ambivalente, c'est un point sur lequel on peut encore débattre.
== IV. Troisième partie (536d-541e) : retour à la ''technê'' par l'examen des passages ==
=== 536d-537a : le refus d'Ion et la transition ===
Ion, touché dans sa dignité professionnelle, refuse pourtant la description que Socrate fait de lui. Il ne peut croire qu'il est « hors de lui ou possédé ». Il invite Socrate à venir l'écouter en personne. Socrate esquive une fois encore l{{'}}''epideixis'' et propose une nouvelle question préalable, c'est la troisième partie qui s'ouvre.
La stratégie de cette partie est de reprendre l'hypothèse de la ''technê'' rhapsodique comme si elle était encore vraie, pour en examiner concrètement le contenu. Si Ion est expert de tout ce que dit Homère, sur quoi précisément est-il expert ? Socrate va parcourir une série de passages homériques en demandant, pour chacun, quelle ''technê'' particulière est compétente pour en juger.
=== 537a-c : le passage de l'aurige (Nestor à Antilocos) ===
Socrate se propose de citer un passage sur l'art de l'aurige, mais Ion l'interrompt pour le réciter lui-même : il s'agit d{{'}}''Iliade'' XXIII, 335-340, les conseils de Nestor à son fils Antilocos pour prendre le tournant dans la course funèbre en l'honneur de Patrocle. Question : qui jugera le mieux si Homère dit cela correctement, un médecin ou un aurige ? Ion concède : l'aurige, « parce qu'il possède cet art ».
Socrate formule alors le principe de spécialisation des ''technai'' (537c-d) : « À chaque art n'a-t-il pas été accordé par la divinité la fonction de connaître un objet déterminé ? Car ce que nous connaissons par l'art du pilote, nous ne le connaissons pas par celui du médecin ». Le principe s'applique à toutes les ''technai'' (''kata pasôn tôn technôn''). La différence entre les ''technai'' repose sur la différence des objets connus : à objets différents, ''technai'' distinctes ; à même objet, même ''technê'' (illustration : l'arithmétique, par laquelle Socrate et Ion savent tous deux qu'il y a cinq doigts à la main).
Corollaire (538a-b) : celui qui ne possède pas une ''technê'' n'est pas capable de juger ce qui est dit ou fait selon cette ''technê''. Par conséquent, pour le passage sur la course de chars, c'est l'aurige qui juge, non Ion. La distinction est cruciale : posséder la ''technê'' rhapsodique, si elle existe, n'est pas posséder la ''technê'' de l'aurige. Le rapsode est expert ''en tant que rapsode'', non en tant qu'aurige.
On peut signaler ici une objection connue, formulée notamment par Goethe : à la question de savoir si l'aurige ou le poète juge mieux ce que Nestor dit à Antilocos, on pourrait soutenir que le poète juge mieux, ''en tant que poète'', car l'aurige saurait seulement si Homère dit des choses techniquement exactes, tandis que le poète saurait si Homère les dit ''de manière convenable'' pour sa fiction. L'argument socratique suppose en réalité qu'il n'y a pas de critère proprement poétique distinct des critères techniques. Pour qui n'accorde pas cette prémisse, une partie de la démonstration perd de sa force.
=== 538b-d : le médecin, le pêcheur ===
Socrate enchaîne les exemples :
* Le médecin (538b-c) : le passage où Hécamède verse au blessé Machaon une boisson de vin pramnien avec du fromage de chèvre râpé (''Iliade'' XI, 639-640). Qui juge ? La médecine, pas la rhapsodie.
* Le pêcheur (538d) : le passage où un plomb descend dans l'eau « pour apporter malheur aux poissons voraces » (''Iliade'' XXIV, 80-82). Qui juge ? La pêche, pas la rhapsodie.
=== 538e-539d : le devin et l'élargissement de la liste ===
Socrate anticipe avec une ironie fine qu'Ion pourrait lui demander si la ''technê'' du devin fait aussi partie de celles capables de juger Homère. Oui, répond-il, et il cite deux exemples :
* La prophétie du devin Théoclymène, descendant de Mélampous, aux prétendants dans l{{'}}''Odyssée'' XX, 351-357 (« Malheureux ! Quel mal vous frappe ? ») ;
* L'augure du combat où un aigle porte un serpent vivant sur l'armée troyenne, en ''Iliade'' XII, 200 et suiv.
Le mouvement est révélateur : à mesure que Socrate parcourt la poésie homérique, il indique que ''chaque passage'' relève de la compétence d'une ''technê'' particulière ''autre que la rhapsodie''. Le rapsode n'est expert ni en conduite de char, ni en médecine, ni en pêche, ni en divination. Que reste-t-il, alors, à la ''technê'' rhapsodique ?
=== 539e-540b : la question inverse ===
Socrate retourne la question à Ion : puisque tu es plus expérimenté que moi en matière homérique, dis-moi toi-même quels sont les passages qui concernent spécifiquement le rapsode et sa ''technê'', ceux qu'il lui revient, à lui plus qu'à tout autre, d'examiner et de juger.
Ion répond avec grandiloquence : « Tous, Socrate ». Socrate pointe immédiatement la contradiction : l'ordre vient d'être établi qu'à ''technê'' distincte correspond objet distinct ; Ion a reconnu que la ''technê'' rhapsodique était distincte des autres ; donc elle ne peut pas connaître ''tous'' les objets. Ion se rétracte : « Tous sauf, peut-être, ces choses-là », c'est-à-dire, précise Socrate, « à peu près tout ce qui concerne les ''autres technai'' ».
Ion tente alors une formulation plus étroite (540b) : ce que le rapsode connaîtrait, ce serait « les choses qui conviennent à un homme, à une femme, à un esclave, à un libre, à un gouverné, à un gouvernant ». Mais Socrate démonte cette défense en série : ce qui convient de dire à un pilote dans la tempête, le pilote le sait mieux ; ce qui convient au malade, le médecin le sait mieux ; à l'esclave bouvier face à un bœuf enragé, le bouvier le sait mieux ; à la fileuse sur le travail de la laine, la fileuse le sait mieux…
=== 540d-541c : le repli sur le général (''stratêgos'') ===
Acculé, Ion joue alors une dernière carte : le rapsode connaîtrait ce qui convient de dire à un général qui harangue ses soldats. Socrate feint la surprise : « L'art du rapsode serait-il donc celui du général ? » Ion affirme qu'il connaîtrait effectivement ce qui convient à un général, et Socrate rétorque : « Alors tu es peut-être aussi doué pour la stratégie, Ion ». La question suit : quand tu distingues les bons chevaux, le fais-tu en tant que cavalier ou en tant que citharède ? En tant que cavalier. Mais, pour les affaires militaires, les connais-tu en tant que bon rapsode ou en tant que général ?
Ion s'égare : « Il me semble qu'il n'y a pas de différence ». Socrate resserre la prise : « Comment, pas de différence ? L'art du rapsode et celui du général sont-ils un seul art, ou bien deux ? », « Il me semble que c'est un seul art ». Socrate en tire alors la conclusion (541a) : tout bon rapsode est donc bon général, et inversement. Ion accepte la première implication mais refuse la seconde, il pense donc que le bon rapsode est nécessairement bon général, mais que le bon général n'est pas nécessairement bon rapsode.
Cette dissymétrie éclaire la structure de la croyance d'Ion : pour lui, le critère fondamental du savoir semble être l'habileté rhétorique et l'effet émotionnel sur l'auditoire. Puisque le général doit galvaniser ses hommes, et que le rapsode maîtrise cet art, le rapsode englobe le général, mais pas l'inverse. Ion confond alors la performance discursive avec la compétence pratique : le général sur le champ de bataille doit connaître les manœuvres, le terrain, l'ennemi, la logistique, et non seulement exhorter.
Socrate pousse l'argument à son terme (541b) : puisque Ion est le meilleur rapsode de Grèce, il serait donc aussi le meilleur général de Grèce. Pourquoi alors ne commande-t-il pas des armées ? Parce que, répond Ion à côté de la question, sa cité (Éphèse) est sous tutelle athénienne et n'a pas besoin de général, et ni les Athéniens ni les Lacédémoniens ne le choisiraient, pensant se suffire à eux-mêmes.
Socrate, ironique, renverse alors cet argument (541c-d) en citant des généraux ''étrangers'' que les Athéniens ont effectivement élus, Apollodore de Cyzique, Phanosthène d'Andros, Héraclide de Clazomènes. Éphèse n'est pas une cité inférieure, et les Éphésiens sont Athéniens par origine (cf. Strabon, XIV, 1 ; Pausanias, VII, 2, 5). Les Athéniens pourraient très bien élire Ion d'Éphèse s'il était vraiment un bon général.
Le choix du ''stratêgos'' comme ''technê'' ultime n'est pas indifférent : cette fonction est élective à Athènes (contrairement à la plupart des magistratures, tirées au sort), ce qui suppose que les citoyens identifient le savoir militaire comme un savoir ''réel'', vital pour la survie de la polis. Hors du théâtre où Ion manipule les émotions du public, la pratique politique concrète paraît reposer sur une distinction implicite entre savoir effectif et performance rhétorique. Goethe jugeait sévèrement la « méchanceté proprement aristophanesque » de ce passage ; d'autres commentateurs y voient au contraire l'un des arguments décisifs du dialogue, en ce qu'il oblige Ion à choisir entre un savoir sérieux et une simple pose.
=== 541e : la rupture du dialogue ===
Socrate rompt alors le dialogue avec le « ἀλλὰ γάρ », « mais en réalité ». Ce marqueur, comme le souligne Rijksbaron, est particulièrement abrupt : Socrate se prive lui-même de la possibilité de continuer à questionner Ion, pour passer au résumé conclusif. Le ton se raidit. L'emploi de l'indicatif conditionnel (''ei alêthê legeis'', « si tu dis la vérité ») marque un scepticisme manifeste.
== V. Épilogue (541e-542b) : le dilemme final ==
=== 541e-542a : l'accusation ===
Socrate formule directement son accusation. Ion est ''adikos'' (injuste) : il a promis une ''epideixis'' sur Homère (530d4-5), il a prétendu posséder une connaissance à prétention universelle, il a maintenu qu'il ''connaissait beaucoup de belles choses'' sur le poète, mais il n'a cessé d'esquiver la démonstration que Socrate lui réclamait. Comme Protée, le dieu marin de l{{'}}''Odyssée'' IV (capture par Ménélas aux vers 384-461), dont la capacité de métamorphose est proverbiale, et que Platon utilise dans l{{'}}''Euthydème'' 288b-c pour critiquer les sophistes, Ion prend mille formes, « va de haut en bas », jusqu'à se présenter comme général pour ne pas avoir à montrer en quoi il est « habile dans la sagesse homérique ».
L'analogie protéenne prend ici tout son sens. Protée change de forme pour échapper à qui voudrait lui arracher la vérité. Ion, de même, change d'identité professionnelle, rapsode, juge de ''technai'', conseiller de rôles sociaux, général, pour ne pas avoir à produire le contenu positif de sa ''technê''. On peut suivre Aguirre lorsqu'il voit dans cette figure l'image d'un savoir sans identité stable, dont la consistance n'excède pas le temps du spectacle.
=== 542a-b : l'alternative ===
Socrate pose alors la dichotomie finale, dans une construction conditionnelle rigoureuse :
* Si Ion possède une ''technê'' (''ei men… technikos ôn'') et ne l'a pas montrée, alors il ment et il est injuste (''adikos'') envers Socrate.
* Si Ion ne possède pas de ''technê'' (''ei de mê technikos ei'') mais est « possédé par Homère par ''theia moira'' » et dit sans savoir beaucoup de belles choses, alors il n'est pas injuste.
« Choisis donc ce que tu préfères qu'on te considère : homme injuste ou homme divin (''adikos anêr einai ê theios'') ».
La structure du dilemme est exemplaire de l'ironie socratique. Formellement, elle offre un choix. Mais les deux termes ne sont pas équivalents dans le lexique du dialogue :
* Être ''technikos'' supposerait que l'on possède un savoir authentique, or Ion vient de reconnaître, passage après passage, qu'il n'en a aucun clairement identifiable. Choisir cette branche supposerait d'admettre une certaine imposture.
* Être ''theios'' sonne flatteusement, mais c'est, dans le lexique platonicien tel qu'il s'est déployé dans l{{'}}''Ion'', proche d{{'}}''ekphrôn'' : possédé, sans savoir, simple canal. La noblesse apparente peut ainsi dissimuler, pour qui relit tout le dialogue, un statut de médiateur passif.
Ion tranche : « Il y a une grande différence, Socrate : il est bien plus beau d'être considéré divin ». Socrate conclut : « Eh bien, le plus beau est à ton actif : tu es, selon nous, un louangeur d'Homère parce que tu es divin et non technicien (''theios kai mê technikos'') ». Les derniers mots font écho aux premiers vrais mots de Socrate après le prologue (530b5-11) : l'inclusion est soignée, le dialogue a fait le tour de la question.
Le qualificatif « ''par' hêmin'' » (« auprès de nous », 542b3) que Socrate ajoute mérite attention. Il indique que cette reconnaissance est conditionnelle, relative au point de vue de Socrate et de son petit cercle. On peut, avec Penelope Murray, voir dans cette précision la marque d'une réserve ironique : l'idée qu'Ion soit inspiré serait, ''aux yeux de Socrate'', une hypothèse de travail plutôt qu'une conviction pleine. L{{'}}''ho Iôn'' solennel du début peut ainsi devenir ''theios Iôn'', mais dans un sens qui n'est pas nécessairement celui qu'Ion lui-même entend.
== VI. La portée philosophique du dialogue ==
=== 1. La dualité structurante : ''technê'' et ''enthousiasmos'' ===
L'architecture conceptuelle du dialogue repose sur l'opposition entre deux modèles du savoir :
* La ''technê'' est rationnelle, communicable, spécifique à un domaine d'objets, et implique la capacité de rendre raison de son savoir (''logon didonai''). Elle est le modèle du savoir véritable que Platon thématisera pleinement dans le ''Gorgias'' et la ''République''.
* L{{'}}''enthousiasmos'' (ou ''theia moira'', ou ''theia dynamis'') est non rationnel, opaque, transitoire, imprévisible, et ne se transmet pas par enseignement. Il produit des effets, parfois de beaux poèmes, mais ne constitue pas, dans les termes du dialogue, un savoir.
Cette opposition est structurante. Les parties I et III (réfutation par la ''technê'') encadrent le noyau central (description de l{{'}}''enthousiasmos''). En ne laissant à Ion, au bout du compte, que l{{'}}''enthousiasmos'', le dialogue tend à placer l'activité poétique en marge de ce qu'il nomme savoir rationnel.
Aristote contredira ce point de vue dans la ''Poétique'' (1460b14-15) : « la rectitude de la politique et celle de l'art poétique ne sont pas la même, ni celle d'un autre art et celle de l'art poétique ». Pour le Platon de l{{'}}''Ion'' au moins, en revanche, la poésie, tant qu'elle est rapportée à l{{'}}''enthousiasmos'', semble ne pas pouvoir fournir de fondement à la pédagogie du citoyen. Reste que ce jugement n'épuise pas nécessairement la pensée platonicienne sur la poésie : le ''Phèdre'' (245a) distingue plusieurs formes de ''mania'' et accorde à l'inspiration poétique une place positive, ce qui invite à lire l{{'}}''Ion'' moins comme un dernier mot que comme une pièce d'un ensemble plus mobile.
=== 2. L'enjeu éducatif et politique ===
Le dialogue ne se réduit pas à une querelle esthétique. L'enjeu porte sur le modèle d'éducation du citoyen grec. La culture grecque traditionnelle repose en partie sur la ''paideia'' homérique : on apprend à vivre en mémorisant, chantant, interprétant les poèmes épiques, considérés comme dépositaires du savoir éthique, politique, militaire, religieux. Les rapsodes, et surtout les poètes, prétendent être les pédagogues du peuple.
En déniant à la poésie le statut de ''technê'', le dialogue tend à contester aux poètes et rapsodes ce droit pédagogique. Si Homère ne possède aucun savoir véritable, ni en médecine, ni en stratégie, ni en gouvernement, ni en éducation, alors il ne peut guider le citoyen vers l'excellence morale. Ce thème sera repris et systématisé dans la ''République'' X, 599b-e, où Socrate demande à Homère : « Quelle guerre se rappelle-t-on qu'il ait bien conduite ? Quelle cité a-t-il fondée ? Quelle loi a-t-il donnée ? » Aucune. L{{'}}''Ion'' peut donc être lu, de ce point de vue, comme une anticipation de la critique plus large développée dans la ''République''.
La métaphore de la chaîne magnétique peut, sous cet angle, être lue comme portant un diagnostic politique. L'unité qu'elle décrit serait précaire : elle naît dans le moment du spectacle, s'évanouit à sa fin ; elle homogénéise les différences individuelles et sociales ; elle repose sur la connexion des émotions ; elle suspend, pour un temps, l'autonomie rationnelle. À cette unité que l'on peut appeler liturgique, Platon oppose, non dans l{{'}}''Ion'' lui-même, mais dans l'ensemble de son œuvre, une unité plus durable, celle qu'assure selon lui l'examen philosophique. Il faut se garder, pour autant, de faire dire au seul ''Ion'' ce qui n'apparaît clairement que dans la ''République''.
=== 3. La figure du rapsode comme intermédiaire compromis ===
Le choix de faire dialoguer Socrate avec un rapsode plutôt qu'avec un poète n'est pas anodin. Le rapsode cumule deux fonctions problématiques :
* il est récitant, avec une dimension émotionnelle et collective ;
* il est interprète (exégète), avec une prétention à éclairer le texte.
Cette double fonction permet à Platon d'étendre la critique : en visant le rapsode, il atteint à la fois la performance publique de la poésie et la prétention interprétative (notamment les interprétations allégoriques évoquées en 530c-d, celles de Métrodore de Lampsaque, Stésimbrote de Thasos, Glaucon). Dans une culture largement orale, poète et rapsode constituent deux moments inséparables du même processus poétique, ce que la métaphore de la chaîne magnétique représente par les anneaux successifs.
Le rapsode apparaît par ailleurs comme un parent des sophistes : vie itinérante, exhibitions rémunérées (''epideixis''), culte de la performance oratoire, relation mercenaire au public. Dans l{{'}}''Hippias Mineur'' et l{{'}}''Hippias Majeur'', Platon tisse explicitement cette connexion.
=== 4. L{{'}}''hermêneus'' et la question de la médiation ===
La notion d{{'}}''hermêneus'' mérite attention. Au début du dialogue (530c), le rapsode est ''hermêneus'' au sens d{{'}}interprète qui explique, commente, éclaire la pensée du poète. Dans la partie centrale (534e, 535a), le terme se déplace : les rapsodes deviennent ''hermêneis hermêneôn'', « interprètes d'interprètes », c'est-à-dire simples intermédiaires d'un message dont ni eux ni les poètes ne sont les auteurs. La médiation herméneutique active tend à se transformer en transmission passive. Ce glissement du même mot trace, à lui seul, une bonne partie de la trajectoire argumentative du dialogue.
Il soulève, accessoirement, une question générale : peut-on comprendre un texte dont on ne partage pas le savoir, dont on n'est pas soi-même l'auteur ? Le Socrate de l{{'}}''Ion'' semble répondre que l'interprétation authentique suppose la possession d'une ''technê'' sur le contenu interprété. D'autres dialogues, et d'autres traditions interprétatives, donneront des réponses différentes.
=== 5. La dimension comique et l'ironie ===
L{{'}}''Ion'' a aussi une dimension comique assumée. Aguirre rapproche Ion du type de l{{'}}''alazôn'' (le fanfaron qui se donne pour plus qu'il n'est) et Socrate de l{{'}}''eirôn'' (celui qui se diminue) de la comédie ancienne. L'opposition est adoucie par Platon : Ion n'est pas un rustre grotesque, il est affable et sincèrement intéressé par la conversation ; Socrate n'est ni sarcastique ni humiliant, et reste dans le registre de son ironie habituelle. Le comique naît des décalages, la solennité du salut initial, la vanité d'Ion, l'absurde du raisonnement sur la stratégie, la grandiloquence du « Tous, Socrate ! » face à la demande de préciser une compétence. Cette tonalité comique n'est pas étrangère à la gravité philosophique : elle en est souvent, chez Platon, un vecteur.
=== 6. Poésie, vérité, mensonge ===
L{{'}}''Ion'' effleure enfin la question, qui sera pleinement thématisée dans la ''République'' II (376c-383c), du rapport entre poésie et vérité. Si le poète inspiré ne sait pas ce qu'il dit, il ne peut être tenu pour garant de la vérité de son discours. La poésie peut être belle sans être vraie au sens fort que Platon accorde à ce mot. Elle produit des effets sur l'âme, des ''pathê'' collectifs, mais ne fait pas nécessairement connaître. C'est sur cette base que la ''République'' II accusera Homère et Hésiode d'avoir propagé de fausses représentations des dieux et de nourrir l'ignorance chez leurs auditeurs. L{{'}}''Ion'', plus modestement, prépare ce terrain sans encore le labourer.
== Conclusion ==
L{{'}}''Ion'', malgré sa brièveté, accomplit plusieurs choses à la fois. En une demi-heure de conversation simulée, Platon :
# expose le statut ambigu de la rhapsodie, pratique culturelle centrale dans l'éducation grecque traditionnelle ;
# élabore l'opposition, qui sera durablement féconde, entre ''technê'' rationnelle et transmissible, d'une part, et ''enthousiasmos'' non rationnel et imprévisible, d'autre part ;
# formule l'une des métaphores les plus durables de la poétique occidentale, la chaîne magnétique de l'inspiration,, que Longin, puis les Romantiques, reprendront ;
# anticipe, sur un mode plus restreint, la critique que le livre X de la ''République'' développera contre la poésie mimétique ;
# met en place un schéma socratique typique, où la réfutation dialectique se double d'une fausse concession qui enferme l'interlocuteur dans une alternative contrainte.
À la fin, Ion choisit d'être « divin ». Selon la lecture majoritaire, il y perd beaucoup : la ''technê'' que l'examen lui a contestée, et une part de la parole autonome que la théorie de l'inspiration lui dénie. Selon une lecture plus retenue, il gagne une place, mineure mais non nulle, dans une économie divine de la parole ; reste à savoir quel prix Platon lui-même attache à cette place. Dans les deux cas, ce qui semble clair, c'est que la parole pleinement responsable tend à se déplacer, dans le dialogue, vers la figure du philosophe.
Ce bref texte, longtemps jugé mineur, apparaît à l'examen comme une pièce articulée du dispositif platonicien, une préparation conceptuelle à la « querelle ancienne » (''palaia diaphora'', ''République'' X, 607b) entre philosophie et poésie, dont il pose les premiers termes sans encore les systématiser.
== Plan récapitulatif des grandes articulations ==
{| class="wikitable"
|-
! Passage !! Contenu
|-
| 530a-531a || Prologue : rencontre, salutations, présentation de la rhapsodie, question sur l'exclusivité homérique
|-
| 531a-533c || Première partie : argument du ''tout'', la ''technê'' comme unité de jugement ; exemples (arithmétique, médecine, peinture, sculpture, musique, rhapsodie)
|-
| 533c-534e || Partie centrale I : la pierre magnétique ; les poètes ''entheoi'' ; comparaison avec les corybantes et les bacchantes ; Tynnichos de Chalcis
|-
| 534e-536d || Partie centrale II : les trois anneaux (poète, rapsode, spectateur) ; l'émotion rhapsodique ; conclusion sur la ''theia moira''
|-
| 536d-538d || Troisième partie I : principe de spécialisation des ''technai'' ; analyse des passages (aurige, médecin, pêcheur)
|-
| 538d-540b || Troisième partie II : le devin ; retour à Ion et sa prétention universelle ; repli sur « ce qui convient à chacun »
|-
| 540b-541c || Troisième partie III : l'art du général ; raisonnement par l'absurde ; les généraux étrangers
|-
| 541c-542b || Épilogue : rupture du dialogue ; analogie protéenne ; dilemme final ; choix d'Ion
|}
== Bibliographie ==
=== Éditions, traductions et commentaires ===
* Aguirre Santos, Javier, ''Platón. Platón y la poesía : Ion'', Madrid, Plaza y Valdés (coll. « Clásicos europeos »), 2013.
* Allen, Reginald E. (trad.), ''Plato: Ion, Hippias Minor, Laches, Protagoras'', New Haven / London, Yale University Press, 1996.
* Canto, Monique (trad., introd. et notes), ''Platon, Ion'', Paris, Flammarion (GF), 2{{e}} éd. 2001 (1{{re}} éd. 1989).
* Capuccino, Carlotta, ''Filosofi e rapsodi. Testo, traduzione e commento dello Ione platonico'', Bologna, CLUEB, 2005.
* Heitsch, Ernst (trad. et comm.), ''Platon, Ion oder Über die Ilias'' (''Platon Werke'', Band VII.3), Göttingen, Vandenhoeck & Ruprecht, 1997.
* Méridier, Louis (éd., trad., notice), ''Platon. Œuvres complètes'', t. V, 1{{re}} partie : ''Ion, Ménexène, Euthydème'', Paris, Les Belles Lettres (Collection des Universités de France), 1931 (nombreuses rééditions).
* Murray, Penelope, ''Plato on Poetry. Ion ; Republic 376e-398b ; Republic 595-608b'', Cambridge, Cambridge University Press, 1996.
* Pradeau, Jean-François (trad., introd. et notes), ''Platon, Ion'', Paris, Ellipses, 2001.
* Rijksbaron, Albert (éd.), ''Plato. Ion, or: On the Iliad'', Amsterdam Studies in Classical Philology 14, Leiden / Boston, Brill, 2007.
* Saunders, Trevor J. (trad.), ''Plato, Early Socratic Dialogues'', London, Penguin, 2{{e}} éd. 2005.
* von der Walde, Giselle, ''Poesía y mentira : la crítica de Platón a las poéticas de Homero, Hesíodo y Píndaro en el Ion y en República 2'', Bogotá, Universidad de los Andes, 2010.
* Woodruff, Paul (trad.), ''Plato. Two Comic Dialogues : Ion and Hippias Major'', Indianapolis, Hackett, 1983.
=== Études critiques ===
* Bremer, John, ''Plato's Ion. Philosophy as Performance'', North Richland Hills (Texas), Bibal Press, 2005.
* Brandwood, Leonard, ''The Chronology of Plato's Dialogues'', Cambridge, Cambridge University Press, 1990.
* Diès, Auguste, ''Autour de Platon'', Paris, Beauchesne, 1927.
* Finkelberg, Margalit, ''The Birth of Literary Fiction in Ancient Greece'', Oxford, Clarendon Press, 1998.
* Flashar, Hellmut, ''Der Dialog Ion als Zeugnis platonischer Philosophie'', Berlin, Akademie-Verlag, 1958.
* Ford, Andrew, ''The Origins of Criticism. Literary Culture and Poetic Theory in Classical Greece'', Princeton, Princeton University Press, 2002.
* Heitsch, Ernst, « Die Argumentationsstruktur im Ion », ''Rheinisches Museum für Philologie'' 133, 1990, p. 243-259.
* Janaway, Christopher, ''Images of Excellence. Plato's Critique of the Arts'', Oxford, Clarendon Press, 1995.
* Kahn, Charles H., ''Plato and the Socratic Dialogue. The Philosophical Use of a Literary Form'', Cambridge, Cambridge University Press, 1996.
* Ledbetter, Grace M., ''Poetics Before Plato. Interpretation and Authority in Early Greek Theories of Poetry'', Princeton, Princeton University Press, 2003.
* Levin, Susan B., ''The Ancient Quarrel Between Philosophy and Poetry Revisited. Plato and the Greek Literary Tradition'', Oxford, Oxford University Press, 2001.
* Lowenstam, Steven, « Is Literary Criticism an Illegitimate Discipline ? A Fallacious Argument in Plato's Ion », ''Ramus'' 22, 1993, p. 19-32.
* Moore, John D., « The Dating of Plato's Ion », ''Greek, Roman and Byzantine Studies'' 15, 1974, p. 421-440.
* Morris, Thomas F., « Plato's Ion on What Poetry Is About », ''Ancient Philosophy'' 13, 1993, p. 265-272.
* Murray, Penelope, « Poetic Inspiration in Early Greece », ''Journal of Hellenic Studies'' 101, 1981, p. 87-100.
* Murray, Penelope, « Inspiration and Mimesis in Plato », in A. Barker & M. Warner (éd.), ''The Language of the Cave'', Edmonton, Academic Printing and Publishing, 1992, p. 27-46.
* Nightingale, Andrea W., ''Genres in Dialogue. Plato and the Construct of Philosophy'', Cambridge, Cambridge University Press, 1995.
* Stern-Gillet, Suzanne, « On (Mis)interpreting Plato's Ion », ''Philosophy'' 79, 2004, p. 169-192.
* Tigerstedt, Eugène N., ''Plato's Idea of Poetical Inspiration'', Helsinki, ''Commentationes Humanarum Litterarum'' 44, Societas Scientiarum Fennica, 1969.
* Tigerstedt, Eugène N., « Furor Poeticus : Poetic Inspiration in Greek Literature Before Democritus and Plato », ''Journal of the History of Ideas'' 31, 1970, p. 163-178.
* Verdenius, Willem Jacob, « L'Ion de Platon », ''Mnemosyne'' 11, 1943, p. 233-262.
* Vicaire, Paul, ''Platon : critique littéraire'', Paris, Klincksieck, 1960.
* Westermann, Hartmut, ''Die Intention des Dichters und die Zwecke der Interpreten. Zur Theorie und Praxis der Dichterauslegung in den platonischen Dialogen'', Berlin / New York, De Gruyter, 2002.
* Wilamowitz-Moellendorff, Ulrich von, ''Platon'', Band 2 : ''Beilagen und Textkritik'', Berlin, Weidmann, 1919.
erqqj84ufhce0gc7jp1u2h0u6w5uqn9
Pour lire Platon/Guide des dialogues/Introduction
0
30547
764254
642551
2026-04-21T17:04:18Z
PandaMystique
119061
764254
wikitext
text/x-wiki
<noinclude>{{sous-pages}}</noinclude>
Ce guide des dialogues platoniciens est écrit dans le même esprit que l'ensemble du livre consacré à Platon : fournir au lecteur débutant en philosophie les éléments indispensables pour aborder la pensée de cet auteur. Dans ce but, la présentation de chaque texte se composera de deux parties : d'une part, une introduction qui donnera un exposé de certains des thèmes les plus importants de l'œuvre ; d'autre part, un commentaire qui visera avant tout à éclairer quelques passages difficiles et à fournir des informations sur des personnes, des lieux, des événements historiques.
== Authenticité des dialogues ==
Avant de lire un dialogue attribué à Platon, il convient de se demander s'il est bien de lui. La question peut surprendre : on ne se la pose pas, d'ordinaire, lorsque l'on ouvre Descartes ou Kant. Elle s'impose pourtant pour Platon, comme pour la plupart des auteurs antiques, parce que le corpus qui nous est parvenu sous son nom s'est constitué par sédimentation, et que la tradition scolaire y a intégré, au fil des siècles, des textes dont l'attribution est douteuse ou manifestement fausse. Distinguer le vrai du faux engage ici des enjeux à la fois philologiques et philosophiques : la connaissance que nous avons de Platon dépend, pour une part, de la liste des textes que nous tenons pour authentiques.
=== Le corpus de Thrasylle ===
La forme canonique du corpus platonicien remonte au grammairien Thrasylle de Mendès, astrologue et conseiller de l'empereur Tibère, qui vivait à Rome au début du I{{er}} siècle de notre ère. Soucieux d'éditer Platon sur le modèle des tragiques, Thrasylle a organisé les œuvres en neuf tétralogies, par analogie avec la trilogie tragique augmentée d'un drame satyrique<ref>Diogène Laërce rapporte cette classification dans ''Vies et doctrines des philosophes illustres'', III, 56-61 ; voir l'édition sous la direction de Marie-Odile Goulet-Cazé, Paris, Le Livre de Poche, « La Pochothèque », 1999, livre III. Thrasylle a vraisemblablement adapté une classification plus ancienne due à Aristophane de Byzance (III{{e}} siècle av. J.-C.), qui regroupait les dialogues par trilogies.</ref>. Le total atteint ainsi trente-six œuvres, auxquelles la tradition a joint treize ''Lettres'' et un recueil de ''Définitions''.
La première tétralogie réunit l{{'}}''Euthyphron'', l{{'}}''Apologie de Socrate'', le ''Criton'' et le ''Phédon'' : groupement qui dessine, en filigrane, le procès et la mort de Socrate. La deuxième rassemble le ''Cratyle'', le ''Théétète'', le ''Sophiste'' et le ''Politique''. La troisième se compose du ''Parménide'', du ''Philèbe'', du ''Banquet'' et du ''Phèdre''. La quatrième contient quatre textes à l'authenticité très discutée : l{{'}}''Alcibiade'' (ou ''Alcibiade majeur''), le ''Second Alcibiade'', l{{'}}''Hipparque'' et les ''Rivaux''. La cinquième réunit le ''Théagès'', le ''Charmide'', le ''Lachès'' et le ''Lysis''. La sixième regroupe l{{'}}''Euthydème'', le ''Protagoras'', le ''Gorgias'' et le ''Ménon''. La septième comprend l{{'}}''Hippias majeur'', l{{'}}''Hippias mineur'', l{{'}}''Ion'' et le ''Ménexène''. La huitième contient le ''Clitophon'', la ''République'', le ''Timée'' et le ''Critias''. La neuvième, enfin, rassemble le ''Minos'', les ''Lois'', l{{'}}''Épinomis'' et les ''Lettres''.
=== Dialogues apocryphes ===
Dès l'Antiquité, certains textes de ce corpus ont été mis en doute. Diogène Laërce mentionne une liste de dialogues que, selon lui, nul ne tenait pour authentiques : le ''Midon'', l{{'}}''Éryxias'', l{{'}}''Alcyon'', les ''Sisyphe'', ''Axiochus'', ''Démodocos'', ainsi que quelques autres<ref>Diogène Laërce, ''Vies et doctrines des philosophes illustres'', III, 62.</ref>. La critique moderne a confirmé ce verdict ancien. Mais elle va plus loin : elle rejette aussi un certain nombre de textes intégrés aux neuf tétralogies elles-mêmes. C'est le cas, pour la quasi-totalité des spécialistes, du ''Second Alcibiade'', de l{{'}}''Hipparque'', des ''Rivaux'', du ''Théagès'' et du ''Minos'', tous regroupés dans les quatrième, cinquième et neuvième tétralogies. Leur style, la pauvreté doctrinale qui s'y lit, l'absence de toute trace dans les témoignages antérieurs au Portique conduisent à y voir des écrits de l'ancienne Académie, composés à l'imitation de Platon peu après sa mort<ref>Voir Luc Brisson, « Introduction générale », dans Platon, ''Œuvres complètes'', sous la direction de Luc Brisson, Paris, Flammarion, 2008, p. IX-LXIX ; ainsi que Julia Annas et Christopher Rowe (dir.), ''New Perspectives on Plato, Modern and Ancient'', Washington, Center for Hellenic Studies, 2002.</ref>. L{{'}}''Épinomis'', qui se présente comme une suite des ''Lois'', est le plus souvent attribué à Philippe d'Oponte, disciple de Platon et éditeur des ''Lois'' après la mort du maître<ref>Leonardo Tarán, ''Academica : Plato, Philip of Opus, and the Pseudo-Platonic'' Epinomis, Philadelphie, American Philosophical Society (''Memoirs of the American Philosophical Society'', vol. 107), 1975.</ref>.
=== Dialogues douteux ===
Entre les œuvres incontestées et les apocryphes se situe une zone grise qui a nourri les débats les plus animés. Trois cas méritent d'être mentionnés. L{{'}}''Alcibiade majeur'', d'abord, a joui d'un prestige considérable dans la tradition néoplatonicienne : Proclus et Olympiodore le plaçaient en tête du cursus philosophique, parce qu'on y voyait une introduction à la connaissance de soi. Friedrich Schleiermacher, dans les introductions à sa traduction allemande des dialogues (1804-1828), a contesté son authenticité ; la majorité des chercheurs du XX{{e}} siècle ont suivi son verdict, même si certains, comme Nicholas Denyer ou Julia Annas, ont plaidé récemment pour une authenticité partielle ou entière<ref>Nicholas Denyer (éd.), Plato, ''Alcibiades'', Cambridge, Cambridge University Press, « Cambridge Greek and Latin Classics », 2001, p. 14-26 de l'introduction.</ref>. L{{'}}''Hippias majeur'', ensuite, a fait l'objet d'un débat comparable : sa facture pourrait être celle d'un disciple imitant le style socratique, mais la plupart des éditeurs modernes penchent aujourd'hui pour l'authenticité<ref>Pour un état de la question, voir Paul Woodruff, ''Plato : Hippias Major'', Indianapolis, Hackett, 1982, introduction.</ref>. Le ''Ménexène'', enfin, pose un problème particulier : ce dialogue contient un long discours funèbre, attribué à Aspasie de Milet, qui fait difficulté tant par son ton que par certains apparents anachronismes. Aristote, pourtant, le cite à deux reprises en l'attribuant expressément à Platon, ce qui incline la plupart des critiques à le tenir pour authentique, malgré les réserves que certains expriment<ref>Aristote, ''Rhétorique'', I, 9, 1367 b 8 ; III, 14, 1415 b 30. Pour une discussion, voir Susan Sara Monoson, ''Plato's Democratic Entanglements'', Princeton, Princeton University Press, 2000, chapitre 7.</ref>.
=== Le cas des ''Lettres'' ===
Les treize ''Lettres'' transmises sous le nom de Platon forment un ensemble à part. La tradition les donnait toutes pour authentiques ; la critique moderne a procédé à un tri sévère. Seules trois sont aujourd'hui considérées comme peut-être authentiques : la troisième, la septième et la huitième, toutes relatives aux affaires de Sicile et à la tentative platonicienne de convertir Denys II de Syracuse à la philosophie. La ''Lettre VII'' occupe une place singulière : long récit autobiographique, elle contient la célèbre « digression philosophique » (341 c-345 c) où Platon expose pourquoi il n'a rien écrit, et n'écrira rien, sur ce qui constitue le cœur de sa pensée. Son authenticité a été longtemps tenue pour acquise, notamment par W. K. C. Guthrie et Luc Brisson<ref>Luc Brisson, ''Lettres'', introduction, traduction et notes, Paris, Flammarion, « GF », 1987, rééd. 2004.</ref>. Un ouvrage influent de Myles Burnyeat et Michael Frede a cependant ébranlé ce consensus, en concluant à une probable fabrication posthume<ref>Myles Burnyeat et Michael Frede, ''The Pseudo-Platonic Seventh Letter'', édité par Dominic Scott, Oxford, Oxford University Press, 2015.</ref>. Le débat reste ouvert. Les autres lettres sont, pour la plupart, considérées comme des exercices rhétoriques composés par des membres tardifs de l'Académie.
=== Critères d'authentification ===
Sur quels fondements la critique moderne procède-t-elle à ce tri ? Trois types de critères sont principalement mobilisés. Les premiers sont externes : il s'agit des témoignages des auteurs anciens, et au premier chef ceux d'Aristote, qui cite abondamment les dialogues dans la ''Métaphysique'', la ''Politique'', l{{'}}''Éthique à Nicomaque'' et la ''Poétique''. Tout texte cité par Aristote sous le nom de Platon jouit d'une forte présomption d'authenticité. Les seconds sont stylistiques : les études de stylométrie, dont il sera question plus bas, permettent de comparer la langue d'un dialogue avec celle des œuvres assurément authentiques. Les troisièmes, enfin, sont doctrinaux : l'accord ou le désaccord d'un texte avec les positions prêtées à Platon par la tradition. Ce dernier critère est le plus fragile, car il suppose que l'on sache déjà ce que Platon pense, or c'est précisément l'objet de la lecture. On ne peut donc lui accorder qu'un rôle auxiliaire.
== Chronologie ==
Une fois établie la liste des dialogues authentiques, une autre question se pose : dans quel ordre ont-ils été composés ? Platon, à la différence d'Aristote, ne date aucun de ses textes ; il n'y fait jamais référence explicite à d'autres de ses œuvres. Il faut donc reconstituer la chronologie à partir d'indices. Le problème peut paraître technique, mais ses enjeux philosophiques sont considérables : selon que l'on place le ''Parménide'' avant ou après la ''République'', par exemple, l'interprétation de la théorie des Formes n'est pas la même.
=== Un problème sans solution définitive ===
Il importe d'abord de reconnaître la difficulté intrinsèque du problème. Les indices internes, renvois d'un dialogue à l'autre, allusions à des événements datables, sont rares et parfois ambigus. Le ''Théétète'' fait référence, dans sa scène d'introduction, à une bataille de Corinthe : s'agit-il de celle de 394 ou de celle de 369 av. J.-C. ? Les philologues penchent pour la seconde, ce qui daterait la rédaction du dialogue au plus tôt à la fin des années 360<ref>Pour un examen de la question, voir Auguste Diès, notice au ''Théétète'', dans Platon, ''Œuvres complètes'', tome VIII, 2{{e}} partie, Paris, Les Belles Lettres, « Collection des universités de France », 1924, p. 116-120.</ref>. Le ''Ménexène'' mentionne la paix d'Antalcidas (386), ce qui impose une date postérieure à cet événement. La ''République'', en revanche, ne contient guère d'allusions exploitables, et pour la majorité des dialogues on ne dispose d'aucun point de repère historique véritablement précis.
=== La méthode stylométrique ===
Face à cette pénurie d'indices, la philologie du XIX{{e}} siècle a élaboré une méthode originale : la stylométrie. Son postulat est simple : la langue d'un auteur évolue au cours de sa carrière, et l'on peut mesurer cette évolution en relevant, de façon statistique, la fréquence de certains traits stylistiques, particules, hiatus, rythmes de clausule, tournures de phrase, choix lexicaux.
Le point de départ en est l'ouvrage de l'Écossais Lewis Campbell, ''The Sophistes and Politicus of Plato'', paru en 1867<ref>Lewis Campbell, ''The Sophistes and Politicus of Plato'', Oxford, Clarendon Press, 1867, en particulier l'introduction.</ref>. Campbell a le premier observé que les ''Lois'', dialogue que la tradition plaçait déjà en fin de carrière, partageaient avec le ''Sophiste'', le ''Politique'', le ''Philèbe'', le ''Timée'' et le ''Critias'' un certain nombre de particularités lexicales et rythmiques qui les distinguaient des autres dialogues. On tenait ainsi un « groupe tardif » constitué sur une base linguistique objective.
Cette voie a été développée par Wilhelm Dittenberger, Constantin Ritter et, surtout, par le philosophe polonais Wincenty Lutosławski, qui a forgé en 1897 le terme même de « stylométrie » dans son livre ''The Origin and Growth of Plato's Logic''<ref>Wincenty Lutosławski, ''The Origin and Growth of Plato's Logic, with an Account of Plato's Style and of the Chronology of his Writings'', Londres, Longmans, Green & Co., 1897.</ref>. Au XX{{e}} siècle, les travaux de Gerard Ledger, puis la synthèse de Leonard Brandwood, ont consolidé la méthode en tirant parti du traitement informatique des données<ref>Gerard R. Ledger, ''Re-counting Plato : A Computer Analysis of Plato's Style'', Oxford, Clarendon Press, 1989 ; Leonard Brandwood, ''The Chronology of Plato's Dialogues'', Cambridge, Cambridge University Press, 1990.</ref>.
La stylométrie n'offre pas un classement complet des dialogues, mais elle permet d'isoler avec une forte probabilité le groupe des œuvres tardives. Pour les autres, il faut combiner les indices linguistiques avec des considérations doctrinales et historiques.
=== Les trois grands groupes ===
La majorité des chercheurs s'accorde aujourd'hui pour répartir les dialogues authentiques en trois ensembles, sans prétendre fixer, à l'intérieur de chaque ensemble, un ordre strict.
Le premier groupe, dit des « dialogues de jeunesse » ou « dialogues socratiques », rassemble des textes généralement brefs, souvent aporétiques, centrés sur la définition d'une vertu particulière : ''Apologie de Socrate'', ''Criton'', ''Euthyphron'', ''Ion'', ''Lachès'', ''Lysis'', ''Charmide'', ''Hippias mineur'', ''Protagoras''. On y joint parfois l{{'}}''Euthydème'', le ''Ménexène'', l{{'}}''Hippias majeur'', voire le premier livre de la ''République''. Ces œuvres seraient contemporaines ou peu postérieures au premier voyage de Platon en Sicile (388 av. J.-C.). Leur Socrate est encore proche du personnage historique : il interroge, réfute, mais n'expose aucune doctrine positive, et la plupart des entretiens s'achèvent sur un aveu d'ignorance.
Le deuxième groupe, dit des « dialogues de maturité », comprend le ''Ménon'', le ''Phédon'', le ''Banquet'', la ''République'' (à partir du livre II), le ''Phèdre'' et, selon les auteurs, le ''Cratyle''. On y trouve l'exposition la plus ample de la théorie des Formes et de la doctrine de l'immortalité de l'âme ; c'est là aussi que Platon déploie ses grandes mises en scène littéraires. Leur composition se situerait entre le premier voyage en Sicile et le deuxième (c'est-à-dire, en gros, entre 388 et 367 av. J.-C.). C'est l'époque où la production de l'Académie, fondée vers 387, bat son plein.
Le troisième groupe, dit des « dialogues de vieillesse » ou « dialogues tardifs », contient le ''Parménide'', le ''Théétète'', le ''Sophiste'', le ''Politique'', le ''Philèbe'', le ''Timée'', le ''Critias'' et les ''Lois''. Ces textes, postérieurs au deuxième voyage en Sicile (367), sont marqués par un effort poussé de formalisation logique et méthodologique, notamment par la « méthode de division » mise en œuvre dans le ''Sophiste'' et le ''Politique'', ainsi que par une réflexion critique sur la théorie des Formes elle-même, particulièrement dans la première partie du ''Parménide''.
=== Les points de débat ===
Cette tripartition, reçue par la plupart des manuels, n'est pas exempte de difficultés. Trois questions, en particulier, demeurent ouvertes.
La première concerne le ''Timée''. La tradition le tenait pour tardif, mais Gwilym Ellis Lane Owen a proposé en 1953 de le redater et de le placer avant la ''République'', dans le groupe de maturité<ref>G. E. L. Owen, « The Place of the ''Timaeus'' in Plato's Dialogues », ''The Classical Quarterly'', vol. 3, n° 1-2, 1953, p. 79-95.</ref>. Harold Cherniss lui a répondu point par point dès 1957 et le consensus, après un débat très nourri, est revenu à la position classique<ref>Harold Cherniss, « The Relation of the ''Timaeus'' to Plato's Later Dialogues », ''American Journal of Philology'', vol. 78, 1957, p. 225-266.</ref>. La question, toutefois, n'est pas close.
La deuxième porte sur le ''Parménide''. Ce dialogue présente un jeune Socrate soumis à une critique serrée de la part du vieux Parménide : la théorie des Formes y est attaquée par une série d'arguments, dont le fameux « argument du troisième homme », auxquels Platon ne fournit aucune réfutation explicite. Faut-il y voir une crise interne de la pensée platonicienne, un moment où Platon douterait de sa propre doctrine, ou un exercice dialectique destiné à préparer le lecteur à une refonte de la théorie ? La réponse engage toute l'interprétation des derniers dialogues<ref>Pour une présentation de la question, voir Constance C. Meinwald, ''Plato's Parmenides'', Oxford, Oxford University Press, 1991 ; et, en français, Denis O'Brien, ''Le Non-être : deux études sur le'' Sophiste ''de Platon'', Sankt Augustin, Academia Verlag, 1995.</ref>.
La troisième, enfin, oppose deux lectures générales de l'œuvre. Les lectures dites « développementales », majoritaires aujourd'hui, voient dans le passage d'un groupe à l'autre une véritable évolution de la pensée, avec ses remises en cause, ses progrès et ses renoncements. Les lectures dites « unitariennes », défendues notamment par Paul Shorey au début du XX{{e}} siècle<ref>Paul Shorey, ''The Unity of Plato's Thought'', Chicago, University of Chicago Press, 1903.</ref>, puis par Harold Cherniss, tiennent au contraire que la pensée de Platon est substantiellement stable d'un bout à l'autre des dialogues, et que les différences apparentes tiennent à la diversité des sujets traités ou des interlocuteurs mis en scène. Une position médiane, articulée par Holger Thesleff, refuse la linéarité chronologique elle-même : Platon aurait composé plusieurs dialogues en parallèle, les retouchant au fil des années, de sorte qu'il n'existerait pas un ordre strict mais plusieurs « couches » de rédaction imbriquées<ref>Holger Thesleff, ''Studies in Platonic Chronology'', Helsinki, Societas Scientiarum Fennica (''Commentationes Humanarum Litterarum'', vol. 70), 1982 ; repris et actualisé dans ''Platonic Patterns : A Collection of Studies'', Las Vegas, Parmenides Publishing, 2009.</ref>.
Le lecteur débutant retiendra cette leçon : la chronologie des dialogues est un cadre commode, utile pour orienter la lecture, mais il ne faut pas le prendre pour un fait établi. On peut très bien lire Platon en suivant un autre ordre, thématique, par exemple, sans rien perdre de l'essentiel.
== Pagination ==
Qui ouvre une édition moderne de Platon, qu'il s'agisse de la collection Budé, de la collection GF-Flammarion, de l{{'}}''Oxford Classical Texts'' ou de la ''Loeb Classical Library'', y trouve, en marge du texte, des chiffres et des lettres : « 509 b », « 247 c », « 71 e ». Ces références, qui paraissent énigmatiques au premier abord, constituent en réalité le système de citation universel de Platon, connu sous le nom de « pagination de Stephanus ». Leur emploi mérite d'être expliqué, car elles sont la clef de toute référence précise au texte.
=== Henri Estienne et l'édition de 1578 ===
Henri II Estienne, humaniste et imprimeur parisien (vers 1528-1598), est l'un des plus grands éditeurs de textes grecs de la Renaissance. On lui doit, entre autres monuments, le ''Thesaurus Graecae Linguae'' (1572), dictionnaire de grec ancien qui est resté l'ouvrage de référence pendant près de trois siècles. En 1578, installé à Genève où il s'était réfugié pour raisons religieuses, il publie une édition complète des œuvres de Platon en trois volumes in-folio, sous le titre latin ''Platonis opera quae extant omnia''<ref>''Platonis opera quae extant omnia. Ex nova Ioannis Serrani interpretatione, perpetuis eiusdem notis illustrata'', 3 vol., [Genève], Henri Estienne, 1578.</ref>. Le nom latin d'Estienne étant ''Stephanus'', l'usage international désigne depuis lors cette édition comme celle de « Stephanus ».
Son dispositif typographique est remarquable. Chaque double page présente, à gauche, le texte grec ; à droite, une traduction latine nouvelle, due à Jean de Serres (''Serranus''). Et, afin de faciliter le va-et-vient entre les deux langues, Estienne a divisé chacune de ses pages en cinq sections à peu près égales, désignées, en marge, par les lettres A, B, C, D et E. Pour localiser un passage, il suffit ainsi d'indiquer le numéro de page et la lettre de la section. Par exemple, « ''République'', 509 b » signifie : page 509 du volume où se trouve la ''République'', section B de cette page.
=== Un standard international ===
Cette pagination a connu une fortune exceptionnelle. Dès le XIX{{e}} siècle, elle s'est imposée dans toutes les éditions savantes, et toutes les éditions modernes, y compris les traductions en langues vernaculaires, la reproduisent en marge. Elle joue pour Platon le rôle que joue, pour Aristote, la pagination de l'édition d'Immanuel Bekker (Berlin, Académie royale de Prusse, 1831-1870). Un étudiant qui lit le ''Phédon'' dans la traduction de Monique Dixsaut<ref>Platon, ''Phédon'', traduction, introduction et notes par Monique Dixsaut, Paris, Flammarion, « GF », 1991.</ref> et un commentateur anglo-saxon qui l'étudie dans la version de David Gallop<ref>Plato, ''Phaedo'', translated with notes by David Gallop, Oxford, Clarendon Press, « Clarendon Plato Series », 1975.</ref> peuvent ainsi dialoguer sans ambiguïté, en renvoyant l'un et l'autre à « 72 e » ou à « 100 b ».
=== Usage pratique ===
Dans la pratique, la référence complète comporte trois éléments : le titre du dialogue, le numéro de page Stephanus et la lettre de section. Ainsi ''République'' 514 a renvoie-t-il au début de l'allégorie de la caverne ; ''Phédon'' 72 e-73 a, au passage qui articule la théorie de la réminiscence ; ''Banquet'' 209 e-210 a, au début du fameux discours de Diotime. Lorsque la citation s'étend sur plusieurs pages, on indique la page et la section de début, puis, séparé par un tiret, la page et la section de fin : ''Ménon'' 81 a-86 c, par exemple, pour l'épisode de l'esclave géomètre. À l'intérieur d'une section, certains éditeurs ajoutent encore un numéro de ligne (« Stephanus 509 b 6 » désignera alors la sixième ligne de la section B de la page 509), mais cette précision, courante dans les travaux philologiques, n'est pas indispensable au lecteur ordinaire.
Quelques particularités méritent d'être signalées. L{{'}}''Apologie de Socrate'' occupe, dans la numérotation Stephanus, les pages 17 à 42 du premier volume ; la ''République'', parce qu'elle est de loin l'œuvre la plus étendue, court de la page 327 à la page 621 : toute référence située dans cette fourchette y renvoie, sauf mention contraire. Les ''Lettres'' forment, dans le volume III de l'édition d'Estienne, un ensemble numéroté à part, à partir de la page 309. Pour un petit nombre de textes, principalement les ''Définitions'' et quelques dialogues apocryphes, la pagination Stephanus est moins uniformément utilisée, et l'on trouve parfois des systèmes alternatifs.
Il faut savoir, enfin, que cette pagination ne correspond à aucune division interne du texte voulue par Platon lui-même : il s'agit d'un découpage typographique, commode mais arbitraire. Les livres de la ''République'' ou des ''Lois'', en revanche, reflètent une division éditoriale ancienne, probablement antérieure à Thrasylle, et vraisemblablement héritée de la bibliothèque d'Alexandrie. Les subdivisions par paragraphes ou par chapitres, présentes dans certaines éditions, sont, elles, l'œuvre des traducteurs modernes et peuvent varier de l'une à l'autre. Pour se repérer sans faille dans la littérature secondaire, mieux vaut donc se fier à la pagination Stephanus : elle seule est universellement partagée.
== Notes ==
{{references}}
5ix0f54xnna55z8e6cgel8fidz48n33
Introduire la biodiversité dans la construction et l'urbanisme
0
32474
764242
639407
2026-04-21T15:39:21Z
Lamiot
1916
titre de chapitre + précis
764242
wikitext
text/x-wiki
{{NavDébut|book={{PAGENAME}}|page=Avant-propos|pageText=Continuer}}
__NOTOC__ __NOEDITSECTION__
<div style="background: #EAF5FB; font-size: 120%; margin: 1em auto; padding: 0.3em; text-align: center; width: 70%;">
<div style="background: #EAF5FB; border: 2px solid #fff; padding: 0.3em;">
''Ce livre appartient aux séries [[Architecture]] et [[Écologie]]. Il est actuellement rangé sur l'[[Accueil/Architecture|étagère Architecture]] de la bibliothèque [[Accueil|Wikilivres]]''.
</div>
</div>
<div style="text-align: center;"><div style="color: #000000; font-weight: normal; font-size:300%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Introduire la biodiversité dans la construction et l'urbanisme </div></div>
{| width="100%" align="center" border="0" cellpadding="4" cellspacing="4" |-
| valign="top" width="40%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
[[Image:Acrosfukuoka02.jpg|thumb|150px|right|Bâtiment végétalisé ([[w:Fukuoka|Fukuoka]], Japon)]]
[[File:GreenWallMurVégétal.jpg|thumb|150px|right|Mur végétal intérieur ([[w:Lille|Lille]], France)]]
'''Avant-propos'''
'''Par qui et pour qui est fait ce livre ? '''
Ce livre est fait par et pour des architectes, urbanistes, aménageurs, étudiants, écologues et d'autres professionnels des secteurs publics ou privé du bâtiment et de l'environnement...
Il est aussi fait par et pour des écocitoyens soucieux d’intégrer les principes et critères du développement durable dans l’habitat et l’urbanisme. <br/>Ces derniers comme les premiers peuvent s’y associer en tant que relecteurs, illustrateurs ou contributeurs (dans le texte ou sur la page de discussion) ou simplement profiter du contenu qui leur est offert.
La rédaction de ce livre a commencé en Août 2009.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Architecture|En savoir plus sur l'architecture...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Urbio|En savoir plus sur URBIO (Urban Biodiversity and Design) ...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur le projet de 15ème cible HQE...]]''' </div>
| valign="top" width="60%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
'''Pourquoi ce livre ?'''
Comme l'a confirmé en 2010 la [[w:Conférence mondiale sur la biodiversité de Nagoya (2010)|Conférence mondiale sur la biodiversité de Nagoya]], les questions de climat et de biodiversité comptent maintenant parmi les premières priorités.
<br />''« Stopper la perte de biodiversité à horizon 2010 »'' est l'engagement pris par la France et l'Europe devant le monde (Le Grenelle de l'environnement a montré que cet objectif était largement partagé). L'ONU a pour sa part comme objectif de fortement freiner la perte de biodiversité à cette échéance. Tous les secteurs de la société peuvent y contribuer.
<br />L'architecture et l'urbanisme peuvent également développer de nouveaux moyens de réconcilier les établissements humains avec la nature.
<br />Pour atteindre ces objectifs, il faut former et des milliers ou dizaines de milliers de professionnels et le plus grand nombre possible d'habitants dans le domaine de la Haute qualité environnementale. Or, si de nombreuses formations et ouvrages sont disponibles sur les questions de climat et d'énergie, mi-2009, il n'existait toujours aucun ouvrage francophone (ou anglophone) traitant de manière large ou exhaustive des questions d'intégration de la biodiversité dans le bâti.
Ce projet de wikilivre vise à remédier au manque de ressources francophones, en proposant à ses lecteurs un répertoire des réponses scientifiquement et/ou techniquement validées, ou en cours d'expérimentation que l'on peut aujourd'hui apporter aux questions posées par des citoyens, consommateurs, décideurs ou professionnels confrontés à l'effondrement de plus en plus manifeste et rapide de la diversité biologique. Il s'agit d'autre part de mieux répondre à des phénomènes préoccupant de croissance urbaine, de périurbanisation et de forte artificialisation des espaces agricoles, dans les pays en développement notamment. Les auteurs de ce livre espèrent contribuer à freiner la perte de la biodiversité, en lui redonnant une place dans notre environnement proche. Ce livre ne remplacera ni l'expérience de terrain, ni une bonne formation, mais pourra contribuer à la clarification et au partage de savoir et savoir faire. La biodiversité étant à l'origine des principaux puits de carbone, sa prise en compte par l'urbaniste et l'architecte répond aussi aux grands enjeux climatiques de notre époque.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur la biodiversité...]]''' </div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Pré-requis'''
Des connaissances de bases (ou élaborées pour les chapitres les plus techniques) en architecture et [[w:Aménagement du territoire|aménagement]] sont recommandées, ainsi qu'en matière d'[[w:écologie du paysage|écologie du paysage]], et tout particulièrement en matière de [[w:fragmentation écologique|fragmentation écopaysagère]] et de [[w:réseau écologique|réseau écologique]].
<br />Les auteurs chercheront à partager leurs connaissances de la manière la plus claire possible, afin que tous et chacun puissent en bénéficier.
<br />Un glossaire, des schémas et illustrations, ainsi que des liens bibliographiques et des liens vers des articles de [[w:Wikipédia|wikipédia]] aideront le lecteur qui veut en savoir plus.
</div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Comment participer et collaborer à la rédaction de ce livre ?'''
<br />Chacun peut contribuer à ce projet, par exemple ;
* comme rédacteur;
* comme relecteur/correcteur (''pour faciliter le travail de toute l'équipe, ne pas oublier de remplir la case "résumé" en justifiant les corrections ou modifications de mise en page'');
* comme ''« discutant »'' dans la [[Wikilivres:page de discussion|page de discussion]](il en existe une pour le livre et une par chapitre et page);
* comme illustrateur, photographe, graphiste ou pour la mise en page...
* comme coordinateur du travail fait ou à faire autour d'un chapitre, d'un thème particulier que vous connaissez bien
Ce livre, en cours de construction, est un [[W:Travail collaboratif|projet collaboratif]]. Si vous y trouvez des erreurs, corrigez les directement à l'aide des liens « ''Modifier'' » sur chaque page, ou poser des questions et apportez vos remarques et suggestions en laissant un [[nouveau message]] sur la page de discussion de ce livre. Toute question ou participation est bienvenue !
Dans tous les cas :
* Ne pas hésiter à vous créer un compte ([[Wikilivres:Dialogue entre contributeurs|pour dialoguer avec les autre contributeurs]]) puis à utiliser la page de discussion du projet
* Merci d'utiliser un [[Wikilivres:La neutralité de point de vue|point de vue neutre]], de toujours utiliser des [[Wikilivres:Ressources libres de droit|ressources libres de droit]] et dans la mesure du possible de [[Wikilivres:Citez vos sources|citer vos sources]] afin que d'autres puissent vérifier, améliorer ou compléter votre travail conformément à la [[Wikilivres:Charte pédagogique|charte pédagogique]] de Wikilivre. Merci de ne pas insérer de messages publicitaires ou personnels dans ce livres. Ils en seraient retirés.
* Si sous débutez sur les wiki, voir la [[Aide:Syntaxe#Identification dans les pages de discussion|page d'aide]] pour la syntaxe.
* Il est souvent plus facile de préalablement copier un texte (à partir de votre navigateur) puis de le coller sur votre éditeur favori (Word par exemple) qui vous permettra de le compléter ou vérifier les erreurs typographiques ou grammaticales plus aisément; puis de recopier le tout dans le navigateur, avant une dernière prévisualisation et sauvegarde. Vous pouvez ainsi garder votre propre version de sauvegarde, ou au moins une version vous permettant de travailler hors-ligne.
|}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Sommaire simplifié </div>
#[[/Avant-propos|Avant-propos]]{{25}}
#[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]{{00}}
#[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]{{00}}
#[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]{{00}}
#[[/Quelques conditions de réussite|Quelques conditions de réussite]]{{25}}
#[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]
#[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]{{00}}
#[[/Quelques exemples et études de cas|Quelques exemples et études de cas]]{{00}}
#[[/Perspectives et prospective|Perspectives et prospective (Espaces intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]{{00}}
#[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]{{00}}
#[[/Annexes|Annexes (Check-list, Bibliographie, références, Glossaire)]]{{25}}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Index complet des chapitres et sous-chapitres </div>
#'''[[/Avant-propos|Avant-propos]]'''{{25}}
#'''[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ Biodiversité dans l'environnement bâti : de quoi parlons nous ?|Biodiversité dans l'environnement bâti : de quoi parlons nous ?]]{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)|La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Le cas particulier des insectes|Le cas des insectes (compost, pollinisation, production de miel, cas particuliers des Insectes saproxylophages pollinisateurs ou d'espèces menacées)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La flore|la flore]]''{{00}}
###''[[/Biodiveristé dans l'environnement bâti : de quoi parlons nous ?/La fonge, les lichens|La fonge, les lichens]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Microflore et microbiote|Microflore et microbiote]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Repousser les limites et contraintes habituellement propres aux écosystèmes urbains|Repousser les limites et contraintes habituellement propres aux écosystèmes urbains]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La notion d'espaces verts|La notion d'espaces verts]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Sous l'eau ? (Ports, digues, récifs artificiels...)|Sous l'eau ? (Ports, digues, récifs artificiels...)]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Bien comprendre et utiliser ce livre|Bien comprendre et utiliser ce livre]]{{00}}
###''[[/Bien comprendre et utiliser ce livre/Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte|Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte (jardin, bord de route, fossé, etc.)]]''{{00}}
###''[[/Bien comprendre et utiliser ce livre/Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)|Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Pourquoi intégrer la biodiversité dans l'architecture ?|Pourquoi intégrer la biodiversité dans l'architecture ?]]
###''[[/Pourquoi intégrer la biodiversité dans l'architecture?/Approches plus ou moins fonctionnalistes|Approches plus ou moins fonctionnalistes (Diversité biologique, aménités, qualité de vie, santé, qualité de l'air, fonctions écologiques, toilettes sèches, compostage...)]]''{{00}}
###''[[Pourquoi intégrer la biodiversité dans l'architecture/Approche éthique|Approche éthique]]''{{00}}
###''[[/Pourquoi intégrer la biodiversité dans l'architecture/Approche esthétique|Approche esthétique]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Distinguer|Distinguer]]{{00}}
###''[[/Distinguer/Construction neuve, ou réhabilitation…|Construction neuve, ou réhabilitation…]]''{{00}}
###''[[/Distinguer /Habitation, bâtiment tertiaire, infrastructures…|Habitation, bâtiment tertiaire, infrastructures…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases|Principes écologiques de bases]]{{00}}
###''[[/Principes écologiques de bases/Écotone|Écotone]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Naturalité|Naturalité]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Renaturation|Renaturation (génie écologique)]]''{{00}}
###''[[/Principes écologiques de bases/Écopotentialité|Écopotentialité]]''{{00}}
###''[[/Principes écologiques de bases/Empreinte écologique|Empreinte écologique]]''{{00}}
###''[[/Principes écologiques de bases/Remboursement de la dette écologique|Remboursement de la dette écologique]]''{{00}}
###''[[/Principes écologiques de bases/Réseau écologique local, écoducs|Réseau écologique local (fractalité ?), écoducs]]''{{00}}
##[[/Préalables/Principes écologiques de bases/L'eau, élément vital et structurant|L'eau, élément vital et structurant]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Histoire du concept de prise en compte de la biodiversité dans le bâti|Histoire du concept]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Aspects qualitatifs etquantitatifs|Aspects qualitatifs etquantitatifs]]{{00}}
#'''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]'''{{00}}
##''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier l'existant (état des lieux, sur et autour du site)| Étudier l'existant (état des lieux, sur et autour du site)]]''{{00}}
###''[[/Étudier l'existant (état des lieux, sur et autour du site)/Ressources (eau, air, sol, propagules, connectivité écologique actuelle, etc.)| eau, air, sol, propagules, connectivité écologique actuelle, etc.)]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier le potentiel écologique du site (Écopotentialités)|Étudier le potentiel écologique du site (Écopotentialités)]]{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie rétrospective (cryptobanque de graine, etc)|Écologie rétrospective (cryptobanque de graine, etc)]]''{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie prospective (possibilités de connectivité écologique future)|Écologie prospective (possibilités de connectivité écologique future)]]''{{00}}
## [[/Implanter les espaces verts et les corridors selon l'existant/]] {{00}}
##[[/Définir une stratégie, en fonction d'un "niveau d'ambition"|Définir une stratégie, en fonction d'un "niveau d'ambition"]]{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?|Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?]]''{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones|Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones ; profiter des terrassement et déblais/remblais (cf fondation, poses d'égouts et canalisation, etc) pour remodeler le terrain en y restaurant ou apportant des reliefs |Raccordements, traversées de fossés, routes ou petites rivières poser de petits écoducs, au moins de type lombriduc, à stabiliser par des "greffes de peau"]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étude architecturale|Étude architecturale]]{{00}}
###''[[/Étude architecturale/Critères d'implantation|Critères d'implantation]]''{{00}}
###''[[/Étude architecturale/Plans intégrant les aspects bioclimatiques et la biodiversité|Plans intégrant les aspects bioclimatiques et la biodiversité]]''{{00}}
###''[[/Étude architecturale/Permis de construire|Permis de construire]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Préparer l'évaluation environnementale|Préparer l'évaluation]]{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Durant les travaux|Durant les travaux]]{{00}}
###''[[/Durant les travaux/Protéger l'existant (le sol et la flore notamment) durant les travaux|Protéger l'existant (le sol et la flore notamment) durant les travaux]]''{{00}}
###''[[/Durant les travaux/Limiter le dérangement de la faune (préfabrication)|Limiter le dérangement de la faune (préfabrication) durant les travaux]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)|Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)]]{{00}}
###[[/Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.|Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.]]''{{00}}
###''[[/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)/Rétrocorriger selon les conclusions de l'évaluation|Rétrocorriger selon les conclusions de l'évaluation]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Le cas d'une réhabilitation (bâti ancien)|Le cas d'une réhabilitation (bâti ancien)]]{{00}}
###''[[/Le cas d'une réhabilitation (bâti ancien)/Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs|Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs]]''{{00}}
#'''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ L'enveloppe du bâti elle-même|L'enveloppe du bâti elle-même]]{{00}}
###''[[/L'enveloppe du bâti elle-même /Toitures et terrasses végétalisées (TTV) |Toitures et terrasses végétalisées (TTV) comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même /Murs comme lieux d'accueils de la biodiversité|Murs comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même/vers un "Bio-bardage" ? (un bardage " spécial biodiversité")|vers un "Bio-bardage" ? (un bardage " spécial biodiversité")]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Superstructures|Superstructures (antennes, câbles, etc.) comme éléments-perchoirs ou d'accroche pour la biodiversité ; Intérêts, risques et limites...]]{{00}}
###''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Finitions et aménagements extérieurs (Balcons, pergola, porches et autres.|Balcons, pergola, porches et autres]]''{{00}}
####''[[Finitions et aménagements extérieurs/Balcons, pergolas et biodiversité|Balcons, pergolas et biodiversité]]''{{00}}
####''[[Finitions et aménagements extérieurs/Le cas des Clôtures ; Des clôtures plus perméables à la biodiversité|Des clôtures plus perméables à la biodiversité]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Les fondations|Les fondations]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Vides sanitaires ou zones-tampon| Certains vides sanitaires ou zones-tampon peuvent être utiles à la biodiversité]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces tampons bâtis|Espaces tampons bâtis]]{{00}}
###''[[/Espaces tampons bâtis/Biodiversité Serre, Véranda, patio|Biodiversité Serre, Véranda, patio]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Structures construites périphériques ou secondaires (garage, abri...)|Structures construites périphétiques ou secondaires (garage, abri...)]]{{00}}
###''[[/Structures construites périphériques ou secondaires (garage, abri...)/Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.|Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces périphériques (aménagés)|Espaces périphériques (aménagés)]]{{00}}
###''[[/Espaces périphériques (aménagés)/Jardin (d'agrément, potager, familial...), Allées, cheminements écologiques|Jardin, Allées, cheminements écologiques]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Bonnes pratiques de gestion, fonctionnement, entretien|Bonnes pratiques de gestion, fonctionnement, entretien]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien /Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)|Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)]]''{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quel équilibre entre contrôle et laisser-faire ?|Quel équilibre entre contrôle et laisser-faire ?]]''{{00}}
###[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quels liens entre milieu et fonctionnalités écologiques|Quels liens entre milieu et fonctionnalités écologiques (telles que biodiversité, compostage, lagunage, production d'oxygène, puits de carbone, entretien des microclimats, etc)]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles|Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Éclairage (intérieur et extérieur) et biodiversité|Éclairage (intérieur et extérieur) et biodiversité (cf. Pollution lumineuse et protection de l'environnement nocturne...)]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Le cas des écoducs|Le cas des écoducs]]{{00}}
## [[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/L'eau rendue à la vie|L'eau rendue à la vie (Lagunages, eaux grises, eaux pluviales, noues, fossés, mares, biopiscines et jeux d'eau]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées|Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées pour faciliter la gestion des déchets à risques ("à part" pour des raisons de précaution sanitaires)]]
#'''[[/Quelques conditions de réussite|Quelques conditions de réussite]]'''{{25}}
##[[/Quelques Conditions de réussite/Réunir les informations et compétences nécessaires|Réunir les informations et compétences nécessaires]]
##[[/Quelques Conditions de réussite/Utiliser les potentialités du site et de son environnement|Utiliser les potentialités du site et de son environnement]]
##[[/Quelques Conditions de réussite/Limiter les biocides|Limiter les biocides, y compris dans les produits d'entretien. Choisir des matériaux résissants et éco ou "« biocompatibles »". Préparer les supports en respectant l'environnement. Envisager la préfabrication en atelier.]]
##[[/Quelques Conditions de réussite/Considérer les aspects sociopsychologiques|Considérer attentivement les aspects sociopsychologiques (freins ou moteurs)]]
##[[/Quelques Conditions de réussite/Aménager selon le principe d'un réseau écologique|Aménager en restaurant un « réseau écologique » (Trame verte et bleue)]]
##[[/Quelques Conditions de réussite/Respecter les rythmes biologiques (saisonnalité, cycles écologiques)|Respecter les rythmes biologiques (saisonnalité, cycles écologiques)]]
##[[/Quelques Conditions de réussite/L'amélioration continue, le principe de "Gestion restauratoire"|L'amélioration continue, le principe de "Gestion restauratoire"]]
#'''[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]'''
##[[/Compatibilité entre biodiversité, ville et habitat/Mythes et idées reçues|Mythes et idées reçues]]
##[[La ville opportunités ou menaces pour la faune nocturne ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Interactions entre les arbres et le bâti|Interactions entre les arbres et le bâti]]
##[[/Compatibilité entre biodiversité, ville et habitat/Le lierre abime-t-il les murs ?|Le lierre abime-t-il les murs ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Contrôler les organismes indésirables, invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques|Contrôler les organismes jugés indésirables dans ce contexte (invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques, orties, ronces, chardons) …]]
##[[/Compatibilité entre biodiversité, ville et habitat/L'eau est-elle l'ennemie de la construction ?|L'eau, ennemie de la construction ?]]
##[[Introduire la biodiversité dans la construction et l'urbanisme/Compatibilité entre biodiversité, ville et habitat/On ne pourrait pas se passer des pesticides ?| On ne pourrait pas se passer des pesticides ]]
#'''[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]'''{{00}}
##[[/Sécurité (sanitaire, technique)/Protection matérielle des structures, matériaux de construction et réseaux|Protection matérielle des structures, matériaux de construction et réseaux (installations électriques et téléphoniques, réseaux d'égouts et câbles notamment), tout en facilitant leur entretien]]{{00}}
##[[/Sécurité (sanitaire, technique)/Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)|Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des isolants, à l'intérieur, à l'extérieur|Protection des isolants, à l'intérieur, à l'extérieur]]{{00}}
##[[/Sécurité (sanitaire, technique)/Biodiversité et hygiène/Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène|Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des canalisations et réseaux souterrains|Protection des canalisations et réseaux souterrains]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des fondations|Protection des fondations]]{{00}}
##[[/Sécurité (sanitaire, technique)/Cheminées et autres conduits de fumée ou aération|Cheminées et autres conduits de fumée ou aération]]{{00}}
#'''[[/Quelques exemples et études de cas|Exemples et études de cas]]'''{{00}}
#'''[[/Perspectives et prospective|Perspectives et prospective (Intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]'''{{00}}
#'''[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]'''{{00}}
#'''[[/Annexes|Annexes]]'''{{25}}
##[[/Annexes/Check-list|Check-list]]{{25}}
##[[/Annexes/Bibliographie|Bibliographie]]{{25}}
##[[/Annexes/Glossaire|Glossaire]]{{25}}
##[[/Annexes/Autres ressources|Autres ressources]]{{00}}
----
{{CDU|7/72/720|720.0/720.0.0}}
{{CDU|3/37/372|372.8/372.89.0}}
----
[[Catégorie:Architecture]]
[[Catégorie:Biologie]]
[[Catégorie:Bricolage|Biodiversité]]
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|*]]
[[Catégorie:Livres en cours de rédaction]]
[[Catégorie:Écologie]]
ta8u1481pcty523ozcuzhkok5wdy5b1
764342
764242
2026-04-22T06:13:02Z
Lamiot
1916
Lien interne ( vers page de discussion
764342
wikitext
text/x-wiki
{{NavDébut|book={{PAGENAME}}|page=Avant-propos|pageText=Continuer}}
__NOTOC__ __NOEDITSECTION__
<div style="background: #EAF5FB; font-size: 120%; margin: 1em auto; padding: 0.3em; text-align: center; width: 70%;">
<div style="background: #EAF5FB; border: 2px solid #fff; padding: 0.3em;">
''Ce livre appartient aux séries [[Architecture]] et [[Écologie]]. Il est actuellement rangé sur l'[[Accueil/Architecture|étagère Architecture]] de la bibliothèque [[Accueil|Wikilivres]]''.
</div>
</div>
<div style="text-align: center;"><div style="color: #000000; font-weight: normal; font-size:300%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Introduire la biodiversité dans la construction et l'urbanisme </div></div>
{| width="100%" align="center" border="0" cellpadding="4" cellspacing="4" |-
| valign="top" width="40%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
[[Image:Acrosfukuoka02.jpg|thumb|150px|right|Bâtiment végétalisé ([[w:Fukuoka|Fukuoka]], Japon)]]
[[File:GreenWallMurVégétal.jpg|thumb|150px|right|Mur végétal intérieur ([[w:Lille|Lille]], France)]]
'''Avant-propos'''
'''Par qui et pour qui est fait ce livre ? '''
Ce livre est fait par et pour des architectes, urbanistes, aménageurs, étudiants, écologues et d'autres professionnels des secteurs publics ou privé du bâtiment et de l'environnement...
Il est aussi fait par et pour des écocitoyens soucieux d’intégrer les principes et critères du développement durable dans l’habitat et l’urbanisme. <br/>Ces derniers comme les premiers peuvent s’y associer en tant que relecteurs, illustrateurs ou contributeurs (dans le texte ou sur la page de discussion) ou simplement profiter du contenu qui leur est offert.
La rédaction de ce livre a commencé en Août 2009.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Architecture|En savoir plus sur l'architecture...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Urbio|En savoir plus sur URBIO (Urban Biodiversity and Design) ...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur le projet de 15ème cible HQE...]]''' </div>
| valign="top" width="60%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
'''Pourquoi ce livre ?'''
Comme l'a confirmé en 2010 la [[w:Conférence mondiale sur la biodiversité de Nagoya (2010)|Conférence mondiale sur la biodiversité de Nagoya]], les questions de climat et de biodiversité comptent maintenant parmi les premières priorités.
<br />''« Stopper la perte de biodiversité à horizon 2010 »'' est l'engagement pris par la France et l'Europe devant le monde (Le Grenelle de l'environnement a montré que cet objectif était largement partagé). L'ONU a pour sa part comme objectif de fortement freiner la perte de biodiversité à cette échéance. Tous les secteurs de la société peuvent y contribuer.
<br />L'architecture et l'urbanisme peuvent également développer de nouveaux moyens de réconcilier les établissements humains avec la nature.
<br />Pour atteindre ces objectifs, il faut former et des milliers ou dizaines de milliers de professionnels et le plus grand nombre possible d'habitants dans le domaine de la Haute qualité environnementale. Or, si de nombreuses formations et ouvrages sont disponibles sur les questions de climat et d'énergie, mi-2009, il n'existait toujours aucun ouvrage francophone (ou anglophone) traitant de manière large ou exhaustive des questions d'intégration de la biodiversité dans le bâti.
Ce projet de wikilivre vise à remédier au manque de ressources francophones, en proposant à ses lecteurs un répertoire des réponses scientifiquement et/ou techniquement validées, ou en cours d'expérimentation que l'on peut aujourd'hui apporter aux questions posées par des citoyens, consommateurs, décideurs ou professionnels confrontés à l'effondrement de plus en plus manifeste et rapide de la diversité biologique. Il s'agit d'autre part de mieux répondre à des phénomènes préoccupant de croissance urbaine, de périurbanisation et de forte artificialisation des espaces agricoles, dans les pays en développement notamment. Les auteurs de ce livre espèrent contribuer à freiner la perte de la biodiversité, en lui redonnant une place dans notre environnement proche. Ce livre ne remplacera ni l'expérience de terrain, ni une bonne formation, mais pourra contribuer à la clarification et au partage de savoir et savoir faire. La biodiversité étant à l'origine des principaux puits de carbone, sa prise en compte par l'urbaniste et l'architecte répond aussi aux grands enjeux climatiques de notre époque.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur la biodiversité...]]''' </div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Pré-requis'''
Des connaissances de bases (ou élaborées pour les chapitres les plus techniques) en architecture et [[w:Aménagement du territoire|aménagement]] sont recommandées, ainsi qu'en matière d'[[w:écologie du paysage|écologie du paysage]], et tout particulièrement en matière de [[w:fragmentation écologique|fragmentation écopaysagère]] et de [[w:réseau écologique|réseau écologique]].
<br />Les auteurs chercheront à partager leurs connaissances de la manière la plus claire possible, afin que tous et chacun puissent en bénéficier.
<br />Un glossaire, des schémas et illustrations, ainsi que des liens bibliographiques et des liens vers des articles de [[w:Wikipédia|wikipédia]] aideront le lecteur qui veut en savoir plus.
</div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Comment participer et collaborer à la rédaction de ce livre ?'''
<br />Chacun peut contribuer à ce projet, par exemple ;
* comme rédacteur;
* comme relecteur/correcteur (''pour faciliter le travail de toute l'équipe, ne pas oublier de remplir la case "résumé" en justifiant les corrections ou modifications de mise en page'');
* comme ''« discutant »'' dans la [https://fr.wikibooks.org/wiki/Discussion:Introduire_la_biodiversit%C3%A9_dans_la_construction_et_l%27urbanisme|page de discussion] (il en existe une pour le livre et une par chapitre et page);
* comme illustrateur, photographe, graphiste ou pour la mise en page...
* comme coordinateur du travail fait ou à faire autour d'un chapitre, d'un thème particulier que vous connaissez bien
Ce livre, en cours de construction, est un [[W:Travail collaboratif|projet collaboratif]]. Si vous y trouvez des erreurs, corrigez les directement à l'aide des liens « ''Modifier'' » sur chaque page, ou poser des questions et apportez vos remarques et suggestions en laissant un [[nouveau message]] sur la page de discussion de ce livre. Toute question ou participation est bienvenue !
Dans tous les cas :
* Ne pas hésiter à vous créer un compte ([[Wikilivres:Dialogue entre contributeurs|pour dialoguer avec les autre contributeurs]]) puis à utiliser la page de discussion du projet
* Merci d'utiliser un [[Wikilivres:La neutralité de point de vue|point de vue neutre]], de toujours utiliser des [[Wikilivres:Ressources libres de droit|ressources libres de droit]] et dans la mesure du possible de [[Wikilivres:Citez vos sources|citer vos sources]] afin que d'autres puissent vérifier, améliorer ou compléter votre travail conformément à la [[Wikilivres:Charte pédagogique|charte pédagogique]] de Wikilivre. Merci de ne pas insérer de messages publicitaires ou personnels dans ce livres. Ils en seraient retirés.
* Si sous débutez sur les wiki, voir la [[Aide:Syntaxe#Identification dans les pages de discussion|page d'aide]] pour la syntaxe.
* Il est souvent plus facile de préalablement copier un texte (à partir de votre navigateur) puis de le coller sur votre éditeur favori (Word par exemple) qui vous permettra de le compléter ou vérifier les erreurs typographiques ou grammaticales plus aisément; puis de recopier le tout dans le navigateur, avant une dernière prévisualisation et sauvegarde. Vous pouvez ainsi garder votre propre version de sauvegarde, ou au moins une version vous permettant de travailler hors-ligne.
|}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Sommaire simplifié </div>
#[[/Avant-propos|Avant-propos]]{{25}}
#[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]{{00}}
#[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]{{00}}
#[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]{{00}}
#[[/Quelques conditions de réussite|Quelques conditions de réussite]]{{25}}
#[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]
#[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]{{00}}
#[[/Quelques exemples et études de cas|Quelques exemples et études de cas]]{{00}}
#[[/Perspectives et prospective|Perspectives et prospective (Espaces intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]{{00}}
#[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]{{00}}
#[[/Annexes|Annexes (Check-list, Bibliographie, références, Glossaire)]]{{25}}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Index complet des chapitres et sous-chapitres </div>
#'''[[/Avant-propos|Avant-propos]]'''{{25}}
#'''[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ Biodiversité dans l'environnement bâti : de quoi parlons nous ?|Biodiversité dans l'environnement bâti : de quoi parlons nous ?]]{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)|La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Le cas particulier des insectes|Le cas des insectes (compost, pollinisation, production de miel, cas particuliers des Insectes saproxylophages pollinisateurs ou d'espèces menacées)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La flore|la flore]]''{{00}}
###''[[/Biodiveristé dans l'environnement bâti : de quoi parlons nous ?/La fonge, les lichens|La fonge, les lichens]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Microflore et microbiote|Microflore et microbiote]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Repousser les limites et contraintes habituellement propres aux écosystèmes urbains|Repousser les limites et contraintes habituellement propres aux écosystèmes urbains]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La notion d'espaces verts|La notion d'espaces verts]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Sous l'eau ? (Ports, digues, récifs artificiels...)|Sous l'eau ? (Ports, digues, récifs artificiels...)]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Bien comprendre et utiliser ce livre|Bien comprendre et utiliser ce livre]]{{00}}
###''[[/Bien comprendre et utiliser ce livre/Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte|Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte (jardin, bord de route, fossé, etc.)]]''{{00}}
###''[[/Bien comprendre et utiliser ce livre/Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)|Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Pourquoi intégrer la biodiversité dans l'architecture ?|Pourquoi intégrer la biodiversité dans l'architecture ?]]
###''[[/Pourquoi intégrer la biodiversité dans l'architecture?/Approches plus ou moins fonctionnalistes|Approches plus ou moins fonctionnalistes (Diversité biologique, aménités, qualité de vie, santé, qualité de l'air, fonctions écologiques, toilettes sèches, compostage...)]]''{{00}}
###''[[Pourquoi intégrer la biodiversité dans l'architecture/Approche éthique|Approche éthique]]''{{00}}
###''[[/Pourquoi intégrer la biodiversité dans l'architecture/Approche esthétique|Approche esthétique]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Distinguer|Distinguer]]{{00}}
###''[[/Distinguer/Construction neuve, ou réhabilitation…|Construction neuve, ou réhabilitation…]]''{{00}}
###''[[/Distinguer /Habitation, bâtiment tertiaire, infrastructures…|Habitation, bâtiment tertiaire, infrastructures…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases|Principes écologiques de bases]]{{00}}
###''[[/Principes écologiques de bases/Écotone|Écotone]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Naturalité|Naturalité]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Renaturation|Renaturation (génie écologique)]]''{{00}}
###''[[/Principes écologiques de bases/Écopotentialité|Écopotentialité]]''{{00}}
###''[[/Principes écologiques de bases/Empreinte écologique|Empreinte écologique]]''{{00}}
###''[[/Principes écologiques de bases/Remboursement de la dette écologique|Remboursement de la dette écologique]]''{{00}}
###''[[/Principes écologiques de bases/Réseau écologique local, écoducs|Réseau écologique local (fractalité ?), écoducs]]''{{00}}
##[[/Préalables/Principes écologiques de bases/L'eau, élément vital et structurant|L'eau, élément vital et structurant]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Histoire du concept de prise en compte de la biodiversité dans le bâti|Histoire du concept]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Aspects qualitatifs etquantitatifs|Aspects qualitatifs etquantitatifs]]{{00}}
#'''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]'''{{00}}
##''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier l'existant (état des lieux, sur et autour du site)| Étudier l'existant (état des lieux, sur et autour du site)]]''{{00}}
###''[[/Étudier l'existant (état des lieux, sur et autour du site)/Ressources (eau, air, sol, propagules, connectivité écologique actuelle, etc.)| eau, air, sol, propagules, connectivité écologique actuelle, etc.)]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier le potentiel écologique du site (Écopotentialités)|Étudier le potentiel écologique du site (Écopotentialités)]]{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie rétrospective (cryptobanque de graine, etc)|Écologie rétrospective (cryptobanque de graine, etc)]]''{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie prospective (possibilités de connectivité écologique future)|Écologie prospective (possibilités de connectivité écologique future)]]''{{00}}
## [[/Implanter les espaces verts et les corridors selon l'existant/]] {{00}}
##[[/Définir une stratégie, en fonction d'un "niveau d'ambition"|Définir une stratégie, en fonction d'un "niveau d'ambition"]]{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?|Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?]]''{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones|Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones ; profiter des terrassement et déblais/remblais (cf fondation, poses d'égouts et canalisation, etc) pour remodeler le terrain en y restaurant ou apportant des reliefs |Raccordements, traversées de fossés, routes ou petites rivières poser de petits écoducs, au moins de type lombriduc, à stabiliser par des "greffes de peau"]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étude architecturale|Étude architecturale]]{{00}}
###''[[/Étude architecturale/Critères d'implantation|Critères d'implantation]]''{{00}}
###''[[/Étude architecturale/Plans intégrant les aspects bioclimatiques et la biodiversité|Plans intégrant les aspects bioclimatiques et la biodiversité]]''{{00}}
###''[[/Étude architecturale/Permis de construire|Permis de construire]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Préparer l'évaluation environnementale|Préparer l'évaluation]]{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Durant les travaux|Durant les travaux]]{{00}}
###''[[/Durant les travaux/Protéger l'existant (le sol et la flore notamment) durant les travaux|Protéger l'existant (le sol et la flore notamment) durant les travaux]]''{{00}}
###''[[/Durant les travaux/Limiter le dérangement de la faune (préfabrication)|Limiter le dérangement de la faune (préfabrication) durant les travaux]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)|Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)]]{{00}}
###[[/Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.|Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.]]''{{00}}
###''[[/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)/Rétrocorriger selon les conclusions de l'évaluation|Rétrocorriger selon les conclusions de l'évaluation]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Le cas d'une réhabilitation (bâti ancien)|Le cas d'une réhabilitation (bâti ancien)]]{{00}}
###''[[/Le cas d'une réhabilitation (bâti ancien)/Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs|Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs]]''{{00}}
#'''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ L'enveloppe du bâti elle-même|L'enveloppe du bâti elle-même]]{{00}}
###''[[/L'enveloppe du bâti elle-même /Toitures et terrasses végétalisées (TTV) |Toitures et terrasses végétalisées (TTV) comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même /Murs comme lieux d'accueils de la biodiversité|Murs comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même/vers un "Bio-bardage" ? (un bardage " spécial biodiversité")|vers un "Bio-bardage" ? (un bardage " spécial biodiversité")]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Superstructures|Superstructures (antennes, câbles, etc.) comme éléments-perchoirs ou d'accroche pour la biodiversité ; Intérêts, risques et limites...]]{{00}}
###''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Finitions et aménagements extérieurs (Balcons, pergola, porches et autres.|Balcons, pergola, porches et autres]]''{{00}}
####''[[Finitions et aménagements extérieurs/Balcons, pergolas et biodiversité|Balcons, pergolas et biodiversité]]''{{00}}
####''[[Finitions et aménagements extérieurs/Le cas des Clôtures ; Des clôtures plus perméables à la biodiversité|Des clôtures plus perméables à la biodiversité]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Les fondations|Les fondations]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Vides sanitaires ou zones-tampon| Certains vides sanitaires ou zones-tampon peuvent être utiles à la biodiversité]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces tampons bâtis|Espaces tampons bâtis]]{{00}}
###''[[/Espaces tampons bâtis/Biodiversité Serre, Véranda, patio|Biodiversité Serre, Véranda, patio]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Structures construites périphériques ou secondaires (garage, abri...)|Structures construites périphétiques ou secondaires (garage, abri...)]]{{00}}
###''[[/Structures construites périphériques ou secondaires (garage, abri...)/Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.|Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces périphériques (aménagés)|Espaces périphériques (aménagés)]]{{00}}
###''[[/Espaces périphériques (aménagés)/Jardin (d'agrément, potager, familial...), Allées, cheminements écologiques|Jardin, Allées, cheminements écologiques]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Bonnes pratiques de gestion, fonctionnement, entretien|Bonnes pratiques de gestion, fonctionnement, entretien]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien /Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)|Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)]]''{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quel équilibre entre contrôle et laisser-faire ?|Quel équilibre entre contrôle et laisser-faire ?]]''{{00}}
###[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quels liens entre milieu et fonctionnalités écologiques|Quels liens entre milieu et fonctionnalités écologiques (telles que biodiversité, compostage, lagunage, production d'oxygène, puits de carbone, entretien des microclimats, etc)]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles|Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Éclairage (intérieur et extérieur) et biodiversité|Éclairage (intérieur et extérieur) et biodiversité (cf. Pollution lumineuse et protection de l'environnement nocturne...)]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Le cas des écoducs|Le cas des écoducs]]{{00}}
## [[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/L'eau rendue à la vie|L'eau rendue à la vie (Lagunages, eaux grises, eaux pluviales, noues, fossés, mares, biopiscines et jeux d'eau]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées|Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées pour faciliter la gestion des déchets à risques ("à part" pour des raisons de précaution sanitaires)]]
#'''[[/Quelques conditions de réussite|Quelques conditions de réussite]]'''{{25}}
##[[/Quelques Conditions de réussite/Réunir les informations et compétences nécessaires|Réunir les informations et compétences nécessaires]]
##[[/Quelques Conditions de réussite/Utiliser les potentialités du site et de son environnement|Utiliser les potentialités du site et de son environnement]]
##[[/Quelques Conditions de réussite/Limiter les biocides|Limiter les biocides, y compris dans les produits d'entretien. Choisir des matériaux résissants et éco ou "« biocompatibles »". Préparer les supports en respectant l'environnement. Envisager la préfabrication en atelier.]]
##[[/Quelques Conditions de réussite/Considérer les aspects sociopsychologiques|Considérer attentivement les aspects sociopsychologiques (freins ou moteurs)]]
##[[/Quelques Conditions de réussite/Aménager selon le principe d'un réseau écologique|Aménager en restaurant un « réseau écologique » (Trame verte et bleue)]]
##[[/Quelques Conditions de réussite/Respecter les rythmes biologiques (saisonnalité, cycles écologiques)|Respecter les rythmes biologiques (saisonnalité, cycles écologiques)]]
##[[/Quelques Conditions de réussite/L'amélioration continue, le principe de "Gestion restauratoire"|L'amélioration continue, le principe de "Gestion restauratoire"]]
#'''[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]'''
##[[/Compatibilité entre biodiversité, ville et habitat/Mythes et idées reçues|Mythes et idées reçues]]
##[[La ville opportunités ou menaces pour la faune nocturne ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Interactions entre les arbres et le bâti|Interactions entre les arbres et le bâti]]
##[[/Compatibilité entre biodiversité, ville et habitat/Le lierre abime-t-il les murs ?|Le lierre abime-t-il les murs ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Contrôler les organismes indésirables, invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques|Contrôler les organismes jugés indésirables dans ce contexte (invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques, orties, ronces, chardons) …]]
##[[/Compatibilité entre biodiversité, ville et habitat/L'eau est-elle l'ennemie de la construction ?|L'eau, ennemie de la construction ?]]
##[[Introduire la biodiversité dans la construction et l'urbanisme/Compatibilité entre biodiversité, ville et habitat/On ne pourrait pas se passer des pesticides ?| On ne pourrait pas se passer des pesticides ]]
#'''[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]'''{{00}}
##[[/Sécurité (sanitaire, technique)/Protection matérielle des structures, matériaux de construction et réseaux|Protection matérielle des structures, matériaux de construction et réseaux (installations électriques et téléphoniques, réseaux d'égouts et câbles notamment), tout en facilitant leur entretien]]{{00}}
##[[/Sécurité (sanitaire, technique)/Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)|Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des isolants, à l'intérieur, à l'extérieur|Protection des isolants, à l'intérieur, à l'extérieur]]{{00}}
##[[/Sécurité (sanitaire, technique)/Biodiversité et hygiène/Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène|Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des canalisations et réseaux souterrains|Protection des canalisations et réseaux souterrains]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des fondations|Protection des fondations]]{{00}}
##[[/Sécurité (sanitaire, technique)/Cheminées et autres conduits de fumée ou aération|Cheminées et autres conduits de fumée ou aération]]{{00}}
#'''[[/Quelques exemples et études de cas|Exemples et études de cas]]'''{{00}}
#'''[[/Perspectives et prospective|Perspectives et prospective (Intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]'''{{00}}
#'''[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]'''{{00}}
#'''[[/Annexes|Annexes]]'''{{25}}
##[[/Annexes/Check-list|Check-list]]{{25}}
##[[/Annexes/Bibliographie|Bibliographie]]{{25}}
##[[/Annexes/Glossaire|Glossaire]]{{25}}
##[[/Annexes/Autres ressources|Autres ressources]]{{00}}
----
{{CDU|7/72/720|720.0/720.0.0}}
{{CDU|3/37/372|372.8/372.89.0}}
----
[[Catégorie:Architecture]]
[[Catégorie:Biologie]]
[[Catégorie:Bricolage|Biodiversité]]
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|*]]
[[Catégorie:Livres en cours de rédaction]]
[[Catégorie:Écologie]]
5cl1atjzco979ibekf9xx46vg3ntewo
764347
764342
2026-04-22T07:56:17Z
Lamiot
1916
764347
wikitext
text/x-wiki
{{NavDébut|book={{PAGENAME}}|page=Avant-propos|pageText=Continuer}}
__NOTOC__ __NOEDITSECTION__
<div style="background: #EAF5FB; font-size: 120%; margin: 1em auto; padding: 0.3em; text-align: center; width: 70%;">
<div style="background: #EAF5FB; border: 2px solid #fff; padding: 0.3em;">
''Ce livre appartient aux séries [[Architecture]] et [[Écologie]]. Il est actuellement rangé sur l'[[Accueil/Architecture|étagère Architecture]] de la bibliothèque [[Accueil|Wikilivres]]''.
</div>
</div>
<div style="text-align: center;"><div style="color: #000000; font-weight: normal; font-size:300%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Introduire la biodiversité dans la construction et l'urbanisme </div></div>
{| width="100%" align="center" border="0" cellpadding="4" cellspacing="4" |-
| valign="top" width="40%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
[[Image:Acrosfukuoka02.jpg|thumb|150px|right|Bâtiment végétalisé ([[w:Fukuoka|Fukuoka]], Japon)]]
[[File:GreenWallMurVégétal.jpg|thumb|150px|right|Mur végétal intérieur ([[w:Lille|Lille]], France)]]
'''Avant-propos'''
'''Par qui et pour qui est fait ce livre ? '''
Ce livre est fait par et pour des architectes, urbanistes, aménageurs, étudiants, écologues et d'autres professionnels des secteurs publics ou privé du bâtiment et de l'environnement...
Il est aussi fait par et pour des écocitoyens soucieux d’intégrer les principes et critères du développement durable dans l’habitat et l’urbanisme. <br/>Ces derniers comme les premiers peuvent s’y associer en tant que relecteurs, illustrateurs ou contributeurs (dans le texte ou sur la page de discussion) ou simplement profiter du contenu qui leur est offert.
La rédaction de ce livre a commencé en Août 2009.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Architecture|En savoir plus sur l'architecture...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Urbio|En savoir plus sur URBIO (Urban Biodiversity and Design) ...]]''' </div>
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur le projet de 15ème cible HQE...]]''' </div>
| valign="top" width="60%" style="border: 1px solid #CCCC99; background-color: #F4EEA1"|
'''Pourquoi ce livre ?'''
Comme l'a confirmé en 2010 la [[w:Conférence mondiale sur la biodiversité de Nagoya (2010)|Conférence mondiale sur la biodiversité de Nagoya]], les questions de climat et de biodiversité comptent maintenant parmi les premières priorités.
<br />''« Stopper la perte de biodiversité à horizon 2010 »'' est l'engagement pris par la France et l'Europe devant le monde (Le Grenelle de l'environnement a montré que cet objectif était largement partagé). L'ONU a pour sa part comme objectif de fortement freiner la perte de biodiversité à cette échéance. Tous les secteurs de la société peuvent y contribuer.
<br />L'architecture et l'urbanisme peuvent également développer de nouveaux moyens de réconcilier les établissements humains avec la nature.
<br />Pour atteindre ces objectifs, il faut former et des milliers ou dizaines de milliers de professionnels et le plus grand nombre possible d'habitants dans le domaine de la Haute qualité environnementale. Or, si de nombreuses formations et ouvrages sont disponibles sur les questions de climat et d'énergie, mi-2009, il n'existait toujours aucun ouvrage francophone (ou anglophone) traitant de manière large ou exhaustive des questions d'intégration de la biodiversité dans le bâti.
Ce projet de wikilivre vise à remédier au manque de ressources francophones, en proposant à ses lecteurs un répertoire des réponses scientifiquement et/ou techniquement validées, ou en cours d'expérimentation que l'on peut aujourd'hui apporter aux questions posées par des citoyens, consommateurs, décideurs ou professionnels confrontés à l'effondrement de plus en plus manifeste et rapide de la diversité biologique. Il s'agit d'autre part de mieux répondre à des phénomènes préoccupant de croissance urbaine, de périurbanisation et de forte artificialisation des espaces agricoles, dans les pays en développement notamment. Les auteurs de ce livre espèrent contribuer à freiner la perte de la biodiversité, en lui redonnant une place dans notre environnement proche. Ce livre ne remplacera ni l'expérience de terrain, ni une bonne formation, mais pourra contribuer à la clarification et au partage de savoir et savoir faire. La biodiversité étant à l'origine des principaux puits de carbone, sa prise en compte par l'urbaniste et l'architecte répond aussi aux grands enjeux climatiques de notre époque.
<div class="noprint" style="text-align:right;margin-right:10px;margin-bottom:4px;">[[Image:Wikipedia-logo.png|16px]] '''[[w:Quinzième cible HQE|En savoir plus sur la biodiversité...]]''' </div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Pré-requis'''
Des connaissances de bases (ou élaborées pour les chapitres les plus techniques) en architecture et [[w:Aménagement du territoire|aménagement]] sont recommandées, ainsi qu'en matière d'[[w:écologie du paysage|écologie du paysage]], et tout particulièrement en matière de [[w:fragmentation écologique|fragmentation écopaysagère]] et de [[w:réseau écologique|réseau écologique]].
<br />Les auteurs chercheront à partager leurs connaissances de la manière la plus claire possible, afin que tous et chacun puissent en bénéficier.
<br />Un glossaire, des schémas et illustrations, ainsi que des liens bibliographiques et des liens vers des articles de [[w:Wikipédia|wikipédia]] aideront le lecteur qui veut en savoir plus.
</div>
|}
{| width="99%" align="center" border="0" cellpadding="4" cellspacing="4" style="border: 1px solid #CCCC99; background-color: #F4EEA1"
|<div align="left">
'''Comment participer et collaborer à la rédaction de ce livre ?'''
<br />Chacun peut contribuer à ce projet, par exemple ;
* comme rédacteur;
* comme relecteur/correcteur (''pour faciliter le travail de toute l'équipe, ne pas oublier de remplir la case "résumé" en justifiant les corrections ou modifications de mise en page'');
* comme ''« discutant »'' dans la [https://fr.wikibooks.org/wiki/Discussion:Introduire_la_biodiversit%C3%A9_dans_la_construction_et_l%27urbanisme|page de discussion] (il en existe une pour le livre et une par chapitre et page);
* comme illustrateur, photographe, graphiste ou pour la mise en page...
* comme coordinateur du travail fait ou à faire autour d'un chapitre, d'un thème particulier que vous connaissez bien
Ce livre, en cours de construction, est un [[W:Travail collaboratif|projet collaboratif]]. Si vous y trouvez des erreurs, corrigez les directement à l'aide des liens « ''Modifier'' » sur chaque page, ou poser des questions et apportez vos remarques et suggestions en laissant un [[nouveau message]] sur la page de discussion de ce livre. Toute question ou participation est bienvenue !
Dans tous les cas :
* Ne pas hésiter à vous créer un compte ([[Wikilivres:Dialogue entre contributeurs|pour dialoguer avec les autre contributeurs]]) puis à utiliser la page de discussion du projet
* Merci d'utiliser un [[Wikilivres:La neutralité de point de vue|point de vue neutre]], de toujours utiliser des [[Wikilivres:Ressources libres de droit|ressources libres de droit]] et dans la mesure du possible de [[Wikilivres:Citez vos sources|citer vos sources]] afin que d'autres puissent vérifier, améliorer ou compléter votre travail conformément à la [[Wikilivres:Charte pédagogique|charte pédagogique]] de Wikilivre. Merci de ne pas insérer de messages publicitaires ou personnels dans ce livres. Ils en seraient retirés.
* Si sous débutez sur les wiki, voir la [[Aide:Syntaxe#Identification dans les pages de discussion|page d'aide]] pour la syntaxe.
* Il est souvent plus facile de préalablement copier un texte (à partir de votre navigateur) puis de le coller sur votre éditeur favori (Word par exemple) qui vous permettra de le compléter ou vérifier les erreurs typographiques ou grammaticales plus aisément; puis de recopier le tout dans le navigateur, avant une dernière prévisualisation et sauvegarde. Vous pouvez ainsi garder votre propre version de sauvegarde, ou au moins une version vous permettant de travailler hors-ligne.
|}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Sommaire simplifié </div>
#[[/Avant-propos|Avant-propos]]{{25}}
#[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]{{00}}
#[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]{{00}}
#[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]{{00}}
#[[/Quelques conditions de réussite|Quelques conditions de réussite]]{{25}}
#[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]
#[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]{{00}}
#[[/Quelques exemples et études de cas|Quelques exemples et études de cas]]{{00}}
#[[/Perspectives et prospective|Perspectives et prospective (Espaces intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]{{00}}
#[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]{{00}}
#[[/Annexes|Annexes (Check-list, Bibliographie, références, Glossaire)]]{{25}}
----
<div style="color: #000000; font-weight: normal; font-size:250%; line-height: 0.8em; margin: 0; padding-top: 0.5em; padding-bottom: 0.25em;"> Index complet des chapitres et sous-chapitres </div>
#'''[[/Avant-propos|Avant-propos]]'''{{25}}
#'''[[/Préalables ; principes généraux et transversaux|Préalables ; principes généraux et transversaux]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ Biodiversité dans l'environnement bâti : de quoi parlons nous ?|Biodiversité dans l'environnement bâti : de quoi parlons nous ?]]{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)|La faune, dont espèces cavernicoles ou plus ou moins associées à l'homme (hirondelle, chouette, cigogne)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Le cas particulier des insectes|Le cas des insectes (compost, pollinisation, production de miel, cas particuliers des Insectes saproxylophages pollinisateurs ou d'espèces menacées)]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/La flore|la flore]]''{{00}}
###''[[/Biodiveristé dans l'environnement bâti : de quoi parlons nous ?/La fonge, les lichens|La fonge, les lichens]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Microflore et microbiote|Microflore et microbiote]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Repousser les limites et contraintes habituellement propres aux écosystèmes urbains|Repousser les limites et contraintes habituellement propres aux écosystèmes urbains]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Changer la notion d'espaces verts|Changer la notion d'espaces verts]]''{{00}}
###''[[/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Sous l'eau ? (Ports, digues, récifs artificiels...)|Sous l'eau ? (Ports, digues, récifs artificiels...)]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Bien comprendre et utiliser ce livre|Bien comprendre et utiliser ce livre]]{{00}}
###''[[/Bien comprendre et utiliser ce livre/Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte|Aspects "Extérieur-intérieur", enveloppe, superstructures et contexte (jardin, bord de route, fossé, etc.)]]''{{00}}
###''[[/Bien comprendre et utiliser ce livre/Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)|Biodiversité plus ou moins fonctionnelle à l'intérieur du bâti, dans l'espace de vie (plantes, aquariums)…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Pourquoi intégrer la biodiversité dans l'architecture ?|Pourquoi intégrer la biodiversité dans l'architecture ?]]
###''[[/Pourquoi intégrer la biodiversité dans l'architecture?/Approches plus ou moins fonctionnalistes|Approches plus ou moins fonctionnalistes (Diversité biologique, aménités, qualité de vie, santé, qualité de l'air, fonctions écologiques, toilettes sèches, compostage...)]]''{{00}}
###''[[Pourquoi intégrer la biodiversité dans l'architecture/Approche éthique|Approche éthique]]''{{00}}
###''[[/Pourquoi intégrer la biodiversité dans l'architecture/Approche esthétique|Approche esthétique]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Distinguer|Distinguer]]{{00}}
###''[[/Distinguer/Construction neuve, ou réhabilitation…|Construction neuve, ou réhabilitation…]]''{{00}}
###''[[/Distinguer /Habitation, bâtiment tertiaire, infrastructures…|Habitation, bâtiment tertiaire, infrastructures…]]''{{00}}
##[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases|Principes écologiques de bases]]{{00}}
###''[[/Principes écologiques de bases/Écotone|Écotone]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Naturalité|Naturalité]]''{{00}}
###''[[/Préalables ; principes généraux et transversaux/Principes écologiques de bases/Renaturation|Renaturation (génie écologique)]]''{{00}}
###''[[/Principes écologiques de bases/Écopotentialité|Écopotentialité]]''{{00}}
###''[[/Principes écologiques de bases/Empreinte écologique|Empreinte écologique]]''{{00}}
###''[[/Principes écologiques de bases/Remboursement de la dette écologique|Remboursement de la dette écologique]]''{{00}}
###''[[/Principes écologiques de bases/Réseau écologique local, écoducs|Réseau écologique local (fractalité ?), écoducs]]''{{00}}
##[[/Préalables/Principes écologiques de bases/L'eau, élément vital et structurant|L'eau, élément vital et structurant]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Histoire du concept de prise en compte de la biodiversité dans le bâti|Histoire du concept]]{{00}}
##[[/Préalables ; principes généraux et transversaux/Aspects qualitatifs etquantitatifs|Aspects qualitatifs etquantitatifs]]{{00}}
#'''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction|Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction]]'''{{00}}
##''[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier l'existant (état des lieux, sur et autour du site)| Étudier l'existant (état des lieux, sur et autour du site)]]''{{00}}
###''[[/Étudier l'existant (état des lieux, sur et autour du site)/Ressources (eau, air, sol, propagules, connectivité écologique actuelle, etc.)| eau, air, sol, propagules, connectivité écologique actuelle, etc.)]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étudier le potentiel écologique du site (Écopotentialités)|Étudier le potentiel écologique du site (Écopotentialités)]]{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie rétrospective (cryptobanque de graine, etc)|Écologie rétrospective (cryptobanque de graine, etc)]]''{{00}}
###''[[/Étudier le potentiel écologique du site (Écopotentialités)/Écologie prospective (possibilités de connectivité écologique future)|Écologie prospective (possibilités de connectivité écologique future)]]''{{00}}
## [[/Implanter les espaces verts et les corridors selon l'existant/]] {{00}}
##[[/Définir une stratégie, en fonction d'un "niveau d'ambition"|Définir une stratégie, en fonction d'un "niveau d'ambition"]]{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?|Espèces-cibles patrimoniales ? ou nature banale (biodiversité ordinaire) ?]]''{{00}}
###''[[/Définir une stratégie, en fonction d'un "niveau d'ambition" /Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones|Evaluer les possibilités de terrassement à fin de diversification et complexification des écotones ; profiter des terrassement et déblais/remblais (cf fondation, poses d'égouts et canalisation, etc) pour remodeler le terrain en y restaurant ou apportant des reliefs |Raccordements, traversées de fossés, routes ou petites rivières poser de petits écoducs, au moins de type lombriduc, à stabiliser par des "greffes de peau"]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Étude architecturale|Étude architecturale]]{{00}}
###''[[/Étude architecturale/Critères d'implantation|Critères d'implantation]]''{{00}}
###''[[/Étude architecturale/Plans intégrant les aspects bioclimatiques et la biodiversité|Plans intégrant les aspects bioclimatiques et la biodiversité]]''{{00}}
###''[[/Étude architecturale/Permis de construire|Permis de construire]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Préparer l'évaluation environnementale|Préparer l'évaluation]]{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Durant les travaux|Durant les travaux]]{{00}}
###''[[/Durant les travaux/Protéger l'existant (le sol et la flore notamment) durant les travaux|Protéger l'existant (le sol et la flore notamment) durant les travaux]]''{{00}}
###''[[/Durant les travaux/Limiter le dérangement de la faune (préfabrication)|Limiter le dérangement de la faune (préfabrication) durant les travaux]]''{{00}}
## [[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)|Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)]]{{00}}
###[[/Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.|Évaluer en perturbant le moins possible la biodiversité (piège à trace, observation à la jumelle, dispositifs d'écoute ou observation à distance, etc.]]''{{00}}
###''[[/Évaluation, et processus d'amélioration continue (quantitatif, qualitatif, tendances)/Rétrocorriger selon les conclusions de l'évaluation|Rétrocorriger selon les conclusions de l'évaluation]]''{{00}}
##[[/Les étapes dans l'élaboration d'un projet de prise en compte de la biodiversité dans la construction/Le cas d'une réhabilitation (bâti ancien)|Le cas d'une réhabilitation (bâti ancien)]]{{00}}
###''[[/Le cas d'une réhabilitation (bâti ancien)/Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs|Désimperméabilisation des sols ; Alternatives aux dalles et dallages jointifs]]''{{00}}
#'''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?|Où, quand et comment intégrer la biodiversité dans et autour du bâti ? <br /> - Lieux et temps d'actions (de l'amont à l'aval du projet) - ]]'''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/ L'enveloppe du bâti elle-même|L'enveloppe du bâti elle-même]]{{00}}
###''[[/L'enveloppe du bâti elle-même /Toitures et terrasses végétalisées (TTV) |Toitures et terrasses végétalisées (TTV) comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même /Murs comme lieux d'accueils de la biodiversité|Murs comme lieux d'accueils de la biodiversité]]''{{00}}
###''[[/L'enveloppe du bâti elle-même/vers un "Bio-bardage" ? (un bardage " spécial biodiversité")|vers un "Bio-bardage" ? (un bardage " spécial biodiversité")]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Superstructures|Superstructures (antennes, câbles, etc.) comme éléments-perchoirs ou d'accroche pour la biodiversité ; Intérêts, risques et limites...]]{{00}}
###''[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Finitions et aménagements extérieurs (Balcons, pergola, porches et autres.|Balcons, pergola, porches et autres]]''{{00}}
####''[[Finitions et aménagements extérieurs/Balcons, pergolas et biodiversité|Balcons, pergolas et biodiversité]]''{{00}}
####''[[Finitions et aménagements extérieurs/Le cas des Clôtures ; Des clôtures plus perméables à la biodiversité|Des clôtures plus perméables à la biodiversité]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Les fondations|Les fondations]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Vides sanitaires ou zones-tampon| Certains vides sanitaires ou zones-tampon peuvent être utiles à la biodiversité]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces tampons bâtis|Espaces tampons bâtis]]{{00}}
###''[[/Espaces tampons bâtis/Biodiversité Serre, Véranda, patio|Biodiversité Serre, Véranda, patio]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Structures construites périphériques ou secondaires (garage, abri...)|Structures construites périphétiques ou secondaires (garage, abri...)]]{{00}}
###''[[/Structures construites périphériques ou secondaires (garage, abri...)/Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.|Clôtures, murs, murets rendus "biocompatibles" et parkings, pylônes, etc.]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Espaces périphériques (aménagés)|Espaces périphériques (aménagés)]]{{00}}
###''[[/Espaces périphériques (aménagés)/Jardin (d'agrément, potager, familial...), Allées, cheminements écologiques|Jardin, Allées, cheminements écologiques]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Bonnes pratiques de gestion, fonctionnement, entretien|Bonnes pratiques de gestion, fonctionnement, entretien]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien /Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)|Quelle temporalité et quel rythme pou les actions de gestion de la biodiversité, avec ou sans biocides, pesticides ? etc.)]]''{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quel équilibre entre contrôle et laisser-faire ?|Quel équilibre entre contrôle et laisser-faire ?]]''{{00}}
###[[/Bonnes pratiques de gestion, fonctionnement, entretien/Quels liens entre milieu et fonctionnalités écologiques|Quels liens entre milieu et fonctionnalités écologiques (telles que biodiversité, compostage, lagunage, production d'oxygène, puits de carbone, entretien des microclimats, etc)]]{{00}}
###''[[/Bonnes pratiques de gestion, fonctionnement, entretien/Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles|Valorisation in situ des déchets verts ; compost, BRF, mulch, chronoxyles]]''{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Éclairage (intérieur et extérieur) et biodiversité|Éclairage (intérieur et extérieur) et biodiversité (cf. Pollution lumineuse et protection de l'environnement nocturne...)]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Le cas des écoducs|Le cas des écoducs]]{{00}}
## [[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/L'eau rendue à la vie|L'eau rendue à la vie (Lagunages, eaux grises, eaux pluviales, noues, fossés, mares, biopiscines et jeux d'eau]]{{00}}
##[[/Où, quand et comment intégrer la biodiversité dans et autour du bâti ?/Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées|Toilettes ou toilettes sèches Toilettes (sans eau) judicieusement positionnées pour faciliter la gestion des déchets à risques ("à part" pour des raisons de précaution sanitaires)]]
#'''[[/Quelques conditions de réussite|Quelques conditions de réussite]]'''{{25}}
##[[/Quelques Conditions de réussite/Réunir les informations et compétences nécessaires|Réunir les informations et compétences nécessaires]]
##[[/Quelques Conditions de réussite/Utiliser les potentialités du site et de son environnement|Utiliser les potentialités du site et de son environnement]]
##[[/Quelques Conditions de réussite/Limiter les biocides|Limiter les biocides, y compris dans les produits d'entretien. Choisir des matériaux résissants et éco ou "« biocompatibles »". Préparer les supports en respectant l'environnement. Envisager la préfabrication en atelier.]]
##[[/Quelques Conditions de réussite/Considérer les aspects sociopsychologiques|Considérer attentivement les aspects sociopsychologiques (freins ou moteurs)]]
##[[/Quelques Conditions de réussite/Aménager selon le principe d'un réseau écologique|Aménager en restaurant un « réseau écologique » (Trame verte et bleue)]]
##[[/Quelques Conditions de réussite/Respecter les rythmes biologiques (saisonnalité, cycles écologiques)|Respecter les rythmes biologiques (saisonnalité, cycles écologiques)]]
##[[/Quelques Conditions de réussite/L'amélioration continue, le principe de "Gestion restauratoire"|L'amélioration continue, le principe de "Gestion restauratoire"]]
#'''[[/Compatibilité entre biodiversité, ville et habitat|Compatibilité entre biodiversité, ville et habitat (mythes, idées reçues et vraies contraintes).]]'''
##[[/Compatibilité entre biodiversité, ville et habitat/Mythes et idées reçues|Mythes et idées reçues]]
##[[La ville opportunités ou menaces pour la faune nocturne ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Interactions entre les arbres et le bâti|Interactions entre les arbres et le bâti]]
##[[/Compatibilité entre biodiversité, ville et habitat/Le lierre abime-t-il les murs ?|Le lierre abime-t-il les murs ?]]
##[[/Compatibilité entre biodiversité, ville et habitat/Contrôler les organismes indésirables, invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques|Contrôler les organismes jugés indésirables dans ce contexte (invasifs, vénéneux, venimeux, abeilles, guêpes et frelons, moustiques, orties, ronces, chardons) …]]
##[[/Compatibilité entre biodiversité, ville et habitat/L'eau est-elle l'ennemie de la construction ?|L'eau, ennemie de la construction ?]]
##[[Introduire la biodiversité dans la construction et l'urbanisme/Compatibilité entre biodiversité, ville et habitat/On ne pourrait pas se passer des pesticides ?| On ne pourrait pas se passer des pesticides ]]
#'''[[/Sécurité (sanitaire, technique)|Aspects ''« Sécurité »'' (sanitaire, technique)]]'''{{00}}
##[[/Sécurité (sanitaire, technique)/Protection matérielle des structures, matériaux de construction et réseaux|Protection matérielle des structures, matériaux de construction et réseaux (installations électriques et téléphoniques, réseaux d'égouts et câbles notamment), tout en facilitant leur entretien]]{{00}}
##[[/Sécurité (sanitaire, technique)/Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)|Préparer et protéger l'enveloppe et toutes ses fonctions (éclairage, étanchéité, entretien, isolation phonique ou thermique, etc)]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des isolants, à l'intérieur, à l'extérieur|Protection des isolants, à l'intérieur, à l'extérieur]]{{00}}
##[[/Sécurité (sanitaire, technique)/Biodiversité et hygiène/Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène|Biodiversité animale, végétale, fongique, microbienne - Santé et Hygiène]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des canalisations et réseaux souterrains|Protection des canalisations et réseaux souterrains]]{{00}}
##[[/Sécurité (sanitaire, technique)/Protection des fondations|Protection des fondations]]{{00}}
##[[/Sécurité (sanitaire, technique)/Cheminées et autres conduits de fumée ou aération|Cheminées et autres conduits de fumée ou aération]]{{00}}
#'''[[/Quelques exemples et études de cas|Exemples et études de cas]]'''{{00}}
#'''[[/Perspectives et prospective|Perspectives et prospective (Intérieurs, habitacles, stations orbitales, habitat lunaire, etc.)]]'''{{00}}
#'''[[/Législation à connaître et respecter pour la prise en compte de la biodiversité dans l'environnement bâti|Législation (''Paradoxes et complexité'')]]'''{{00}}
#'''[[/Annexes|Annexes]]'''{{25}}
##[[/Annexes/Check-list|Check-list]]{{25}}
##[[/Annexes/Bibliographie|Bibliographie]]{{25}}
##[[/Annexes/Glossaire|Glossaire]]{{25}}
##[[/Annexes/Autres ressources|Autres ressources]]{{00}}
----
{{CDU|7/72/720|720.0/720.0.0}}
{{CDU|3/37/372|372.8/372.89.0}}
----
[[Catégorie:Architecture]]
[[Catégorie:Biologie]]
[[Catégorie:Bricolage|Biodiversité]]
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|*]]
[[Catégorie:Livres en cours de rédaction]]
[[Catégorie:Écologie]]
5lhf13mx740wdbklt2mxemk2d722u27
Introduire la biodiversité dans la construction et l'urbanisme/L'enveloppe du bâti elle-même /Murs comme lieux d'accueils de la biodiversité
0
33148
764231
675139
2026-04-21T14:49:00Z
Lamiot
1916
/* Bibliographie */compl
764231
wikitext
text/x-wiki
[[Image:HK Kennedy Town Forbes Street w1.jpg|thumb|upright=1.5|Dans certaines conditions, la végétation - et ici son système racinaire - peut envelopper ou couvrir un mur ancien, en l’abîmant peu, voire en le protégeant (ici à [[Hongk-Hong]])]]
Diverses parties de l'enveloppe ou du support (poteaux, etc) d'une construction peuvent abriter ou faciliter la vie de nombreuses espèces d'animaux et végétaux, sans que cela nuise à la structure ou aux fonctions du bâti si ce dernier est conçu pour empêcher sa dégradation par la faune, la flore et les champignons, et pour empêcher les contacts directs entre la faune et les habitants ou usagers dans le cas de structures habitées.
==L'architecture traditionnelle==
[[File:Ruche pédagogiqueKCC2008Lamiot3.jpg|thumb|left|upright=1.3|Cette ruche "pédagogique" située dans un bâtiment (magasin et lieu de réunion) de l'ONG anglais [http://kentwildlife.smartchange.org/ Kent Wildlife trust] et KMRBC ([http://www.kmbrc.org.uk/aboutus/aboutKMBRC/index.php Kent & Medway Biological Records Centre]) (Kent, Royaume-Uni) permet de voir les abeilles au travers des vitres, d'écouter leur vrombissement, de sentir l'odeur de la ruche, grâce des orifices grillagés ; placée à l'ombre, elle communique avec l'extérieur via un conduit traversant le mur]]
[[File:Bee boles.jpg|thumb|upright=1|Niches dans un mur de brique, abritant des ruches traditionnelles (pour produire miel et cire), mais aussi utile pour polliniser les fruitiers proches (Lost Gardens of Heligan, Cornouaille, Royaume-Uni)]]
[[File:Beehivepubsign.jpg|thumb|upright=1|Enseigne anglaise faite d'une véritable ruche, habitée par des abeilles (Beehive Inn, Grantham, Royaume-Uni]]
* '''Concernant la flore''' : <br />Les toitures végétalisées semblent avoir été courantes et anciennes en Europe du nord.
<br />Des plantes grimpantes (lierre, vigne vierge, chèvre feuille ont également colonisé des murs de toutes sorte depuis longtemps en zone tempérée.
<br />En zone tropicale et équatoriale, la flore (très exubérante) est la faune sauvage sont au contraire maintenue à distance.
* '''Concernant la faune''' : <br />En Europe et Asie du nord, l'habitat humain, les fermes et les châteaux semblent - depuis les débuts de l'histoire de l'architecture - avoir accordé une large place à la faune domestiquée ;
<br />ainsi trouve-ton des traces anciennes de niches et chenils pour les chiens (chiens de garde ou de chasse), poulaillers, chatières... <br>Des écuries et étables adossées à la ferme, ou formant son rez de chaussée étaient fréquent dans le moyen-âge européen.
<br/>Des pigeonniers, voire des ruchers pouvaient être intégrés dans les murs, respectivement pour la récolte de fientes (comme engrais), d’œufs, la viande de pigeon et pour le miel et la cire).
<br />Plusieurs espèces d'hirondelles qui débarrassaient les étables et écuries des nuées de mouches attirées par les animaux et leur fumier sont devenues si proches de l'homme qu'on les caractérise souvent comme [[w:Commensal|commensale]]s de l'homme.
{{clear}}
==L'architecture contemporaine==
Certains architectes, dans les projets où la qualité environnementale est privilégiée, accordent depuis peu une place croissante à la flore, et commencent parfois à intégrer la faune sauvage dans leurs projets. Le concept de « maison-nichoir » a en France été promu par Jean-François Noblet (voir bibliographie)
==Le mur végétalisé==
== Histoire, réhabilitation historiques... ==
[[File:MoutonSoaySoaySheepUrbanGrazing2012LilleLamiotF 03.JPG|thumb|250px|[[w:fr:Mouton de Soay|Moutons de Soay]] utilisés pour la [[w:fr:Gestion restauratoire|gestion restauratoire]] de la végétation couvrant le sommet des murs d'une partie récemment restaurée des fortifications de la [[w:fr:Citadelle de Lille|Citadelle de Lille]]. Très à l'aise sur les pentes, cet animal remplace la tondeuse tout en jouant un rôle de ''[[w:fr:Corridor biologique|corridor écologique]] ambulant'' (il véhicule des [[w:fr:Graine|graine]]s et [[w:fr:Propagule|propagule]]s dans son pelage, son tube digestif et sous ses sabots)]]
[[File:Écomatériaux biodiversité construction Lille 2016 a Citadelle 8.JPG|thumb|left|upright=1.4|Sur une partie des fortifications (contre-garde), une expérimentation en faveur de la biodiversité doit permettre à quelques espèces végétales et animales « muricoles » (invertébrés, chauve-souris) de continuer à vivre sur le site, et faciliter leur observation par le public.<br /> Sur quelques dizaines de mètre des parpaings spéciaux ont été maçonnés avec de la terre, et remplis d'une terre compact (riche en argile et chaux). Les spores et graines sauvages adaptées au milieu sont apportées par le vent, les insectes, les oiseaux, etc. les espèces s'auto-sélectionnent et s'adaptent à ce microclimat particulier (chaud et sec en été, très exposé au vent).]]
[[File:Gabion terre pierre Citadelle Lille biodiversité 2016 Lamiot a.JPG|thumb|left|upright=1.4|Sur quelques mètres, et dans le même objectif que sur l'image ci-dessus, une autre expérience utiliser des [[w:gabion|gabions]] emplis de petites pierres calcaire dure et de terre.]]
La colonisation naturelle de murs et murets par des plantes (dont arbres) est naturelle.
Elle est habituellement considérée comme un problème, les racines endommageant les mortiers naturels de terre ou de chaux hydraulique naturelle, surtout s'ils sont souvent humides. Ces racines peuvent dans certaines conditions, décoller les briques ou encore favoriser l'humidité du mur (ou au contraire la drainer), ou augmenter sa vulnérabilité au gel (ex : cas des murs de fortification dont le cœur est constituée de pierre calcaire gélive, cachées sous un parement protecteur de pierre dure ou de brique). <br />En zone tropicale humide, certains arbres peuvent rapidement coloniser et entièrement recouvrir des architectures (dont patrimoniales telles que celles des temples d'[[w:fr:Angkor|Angkor]] en quelques siècles).
Des structures architectoniques artificielles, ciment ou appareils de pierres maçonnées, que l'on laisse volontairement se couvrir de [[w:Bryophyte|mousse]]s et de quelques plantes [[w:muricole|muricoles]] ([[w:Fougère|fougère]]s notamment) existent néanmoins (depuis plus de 200 ans au moins en France dans quelques grands parcs royaux ou municipaux, initialement toujours associés à des fontaines ou cascades).
Les "fabriques" romantiques (faux bâtiments anciens, fausses ruines) les ont beaucoup apprécié au XIXe siècle.
Ils ont ensuite été développés par certains [[w:zoo|zoos]] et pour le décor de [[w:fr:terrarium|terrarium]]s ou d'[[w:fr:aquaterrarium|aquaterrarium]]s publics ou privés, utilisant généralement des espèces tropicales en culture [[w:hydroponique|hydroponique]]<ref>http://jardin-botanique.ups-tlse.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1221657599742&ID_FICHE=68457 Fiche du Jardin botanique Henri Gaussen, présentant un mur végétal tropical élaboré par Patrick Blanc], pdf, 1 page </ref>, avant que le [[w:fr:Botaniste|botaniste]] et chercheur français [[w:fr:Patrick Blanc|Patrick Blanc]] ne crée, teste et développe son concept [[w:fr:horticulture|horticole]] de ''mur végétal'' sur support de feutre horticole.
D'autres techniques de murs végétaux se développent et dans leur sillage ou indépendamment, des designers et paysagistes ont développé de nouvelles méthodes et outils pour les espaces intérieurs. Des systèmes en kits prévégétalisés à assembler existent <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/technologie-de-realisation-du-mur-vegetal-et-du-jardin-vertical-greenwall.html Système de kits, de Greenwall Végétalis, conçu avec l'aide de scientifiques]</ref> ou de supports conçus avec l'aide de scientifique et d'un logiciel de modélisation de la croissance des plantes (croissance, aspect, couleur...) <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/mur-vegetal-et-jardin-vertical-vivant.html Voir la Animation 4D réalisée par l’ U.M.R A.M.A.P du CIRAD sur une suite logicielle (Orchestra®) de Bionatics.] (consulté 2010/30/08)</ref>, Fedor van der Valk a inventé de minis-jardins suspendus intérieurs (« ''String Gardens'' ») qui semblent flotter dans le vide en supportant des cascades de verdure. Le néo-zélandais Patrick Morris réussit à donner l'impression que le plafond est tapissé de plantes, via des jardinières à double fond qui y sont suspendues. L'équipe d'Amaury Gallon vient installer un mur végétal en kit, installé à domicile. Le designer Richard Grassin Delyle propose des cloisons ou doubles cloisons végétalisées, éventuellement mobiles, avec plantes fixées sur tissus horticole horizontal <ref>[http://www.mur-vegetal-interieur.fr/mur-vegetal.html Présentation des cloisons végétales de Richard Grassin Delyle] (avec réserve d'eau pour 3 à 4 semaines, mais nécessitant une prise électrique)</ref>. De nombreux exemples de murs intérieurs sont aujourd'hui disponibles<ref>[http://aquakarma974.over-blog.com/ Ex : Jardin vertical intérieur de 33 m3 d'Aquakarma 974]</ref>.
Le [[w:Gabion|gabionnage]] a encore donné lieu au XXème siècle à divers [[w:innovation|innovation]]s<ref>ex : CLAUZEL, L. (1963). ''[http://documents.irevues.inist.fr/bitstream/handle/2042/24557/RFF_1963_6_512.pdf?sequence=1? Un nouveau système de gabions: les coffres en treillis d'acier remplis en hérisson]''.</ref> et [[w:brevet (invention)|brevets]]<ref>ex : Hilfiker, W. K. (1991). U.S. Patent No. 5,076,735. Washington, DC: U.S. Patent and Trademark Office (brevet)</ref>, mais leur relative simplicité de fabrication peut permettre comme au [[Burkina Faso]] de les faire fabriquer par des artisans locaux<ref>Royet, P. (1992). Les ouvrages en gabions, [http://agris.fao.org/agris-search/search.do?recordID=FR19960033446 fiche Agris-FAO]</ref>. On a notamment essayé d'y intégrer des fonctions de [[services écosystémiques]] en les rendant parfois plus propices à la [[biodiversité]], par exemple en permettant leur colonisation par des [[w:racine|racine]]s d'[[w:racine|arbre]]s<ref>Koch, D. (1994). ''Essai d'intégration de la végétation dans les gabions sur un chantier de construction de route au Népal central'' (Doctoral dissertation).</ref>
{{clear}}
== Principe ==
[[File:04_-_Végétalis®_chevalets.jpg|thumb|upright=1|left|Des producteurs (ici ''murs végétalis®'') proposent des mélanges d'espèces et de variétés permettant une meilleure résistance aux maladies…]]
[[File:Greenbox®.jpg|thumb|250px|Module ''Greenbox®'']]
[[File:Végétalis® école archi.jpg|thumb|upright=1|Mur végétalis® de l'[[école d'architecture de Montpellier]], don de la société ''Greenwall'']]
[[File:03_-_Cultures_végétalis.jpg|thumb|upright=1|Les plantes préparées sur une surface presque verticale auront un aspect plus naturel dès leur installation sur le mur (Cultures végétalis®)]]
Des murs ou parois végétalisées peuvent être aménagés tant à l'extérieur qu'à l'intérieur de bâtiments, avec ou sans source artificielle de lumière.
<br>Le principe s'appuie sur le fait qu'en l'absence d'intervention humaine, en présence d'air propre et d'une humidité suffisante de l'air, tout support tend à être naturellement colonisé par des bactéries ([[biofilm]]), des [[algue]]s, puis des [[mousse (botanique)|mousse]]s et des [[lichen]]s, avant l'apparition de petites plantes, qui sont généralement aussi des épiphytes des arbres. Dans le cas où le mur reste sec, ou en atmosphère plus sèche, il peut également être colonisé par des plantes grimpantes ([[Lierre grimpant|lierre]], [[vigne vierge]] en [[climat tempéré]]).
<br>Plusieurs approches techniques existent, allant de l'insertion de plantes adaptées aux milieux secs et pauvres (crassulantes, cactées..) pour créer des structure de type ''« jardins de rocailles »'', à des techniques sophistiquées dites de "génie végétal" optimisant les conditions de colonisation et de pousse des plantes grâce à des supports de feutre synthétique dans lequel circule de l'eau enrichie en sels nutritifs.
Un grand nombre de plantes tropicales épiphytes ou poussant à l'ombre de la canopée se contentent de peu de lumière et de peu de nutriments.
== Types d'aménagement de façades ==
Il peut se faire soit à partir du sol directement, les racines de plantes grimpantes y puisant leur nourriture et l'eau, soit en intégrant la flore au bâtiment, via des balconnières, des jardinières, ou des systèmes plus complexe de murs végétaux tels que ceux de [[Patrick Blanc]].
'''Par exemple :''' Sur le mur porteur est placé une ossature métallique qui soutient une plaque de [[Chlorure de polyvinyle|PVC]] expansé de 10 mm d'épaisseur, sur laquelle sont agrafées deux couches de feutre de [[polyamide]] de 3 mm d'épaisseur chacune. Ces couches de feutre miment en quelque sorte les [[mousse (botanique)|mousse]]s qui se développent sur les parois rocheuses et qui servent de support aux [[Racine (botanique)|racines]] des plantes. Un réseau de tuyaux commandés par des électrovannes apporte une [[solution nutritive]] contenant les éléments minéraux nécessaires à la croissance des plantes. Le feutre s'imprègne de cette solution nutritive, qui redescend le long du mur par gravité. Les racines des plantes n'ont qu'à se servir, et l'eau en excès est recueillie en bas du mur par une gouttière, avant d'être réinjectée dans le réseau de tuyaux : le système fonctionne en circuit fermé.
C'est une variation inhabituelle d'une [[machine vivante]] : l'eau s'écoule sur une surface sur laquelle se développent de la [[mousse (botanique)|mousse]] ou d'autres plantes, quelques [[insecte]]s et des [[bactérie]]s, et est captée en bas du mur dans une [[Gouttière (architecture)|gouttière]], d'où elle est réinjectée en haut du mur.
== Les avantages ==
En plus de l'aspect esthétique, le mur végétalisé présente plusieurs avantages :
*Il permet une meilleure régulation thermique du bâtiment. En été, l'ensoleillement est réduit.
*L'[[w:évapotranspirationévapotranspiration]] du lierre ou d'autres grimpantes contribue au rafraîchissement de l'air et à une régulation de l'[[w:Hygrométrie|hygrométrie]]. En hiver, ce couvert végétal seul ne peut jouer un véritable rôle d'[[w:Isolation (construction)|isolant]], mais en asséchant les fondations et en protégeant les murs de la pluie (grâce à l'orientation des feuilles et à leur densité dans le cas du lierre), il les rend plus [[w:Isolant|isolant]]s.
*Il protège le bâtiment contre l'effet corrosif des pollutions urbaines ([[w:Pluie acide|pluie acide]], [[w:Pollution de l'air|pollution atmosphérique]]) et contre l’humidité (acide, en ville), en offrant une surface imperméable à la pluie. En effet, la disposition "en tuiles" des feuilles de certaines grimpantes, telles que le lierre, permet de protéger presque totalement le mur de la pluie.
*Les racines participent à l'assèchement du sol à proximité des fondations.
*La végétalisation des façades offre une surface végétale supplémentaire et significative pour l'épuration de l'air et la production d'oxygène.
*Certains [[w:mur anti-bruit|murs anti-bruit]] sont végétalisés, augmentant leur fonction dé-stressante (végétalis®, Le Prieuré, Héliotrope…). Le feuillage seul est réputé inefficace (une épaisseur de 10 m de feuillage d'arbres ne réduit un son puissant que d'à peine 1 dba), cependant le bruit du vent dans les feuilles et celui des oiseaux (comme celui des fontaines) ont des vertus psychologiquement apaisantes, et sans vraiment cacher le bruit ambiant, ils le rendent plus supportable.
== Utilisation du lierre ==
Le [[Lierre grimpant|lierre]] est une plante particulièrement bien adaptée au verdissement des façades. Sauf dans le cas de murs maçonnés à la [[Chaux (chimie)|Chaux hydraulique naturelle]] ou à la terre et qui seraient assez humides pour que les racines puissent y vivre, ce végétal n'abîme pas les façades, bien qu'il puisse endommager les peintures où ses crampons laissent des traces. Il est résistant aux conditions climatiques rudes ([[inondation]], gel, [[sécheresse]]...). Il reste vert toute l'année, ce qui lui permet de continuer à absorber du carbone pendant l'hiver, alors que la plupart des végétaux ont perdu leurs feuilles. La période de pollinisation du lierre se situe vers la fin de l'été. Il offre donc aux invertébrés pollinisateurs la possibilité de bénéficier d'un dernier approvisionnement en [[pollen]] avant l'hiver. Les fruits du lierre apparaissent très tôt dans l'année (vers le mois de mars), et constituent une nourriture de base pour les oiseaux frugivores, alors que leur nourriture fraîche commence à manquer. De plus, au même titre que certaines autres espèces indigènes ([[fougère]]s, [[cymbalaire]]), le lierre possède une valeur esthétique.
Les autres espèces couramment utilisées sont la [[vigne vierge]], le [[chèvrefeuille]]...
== Entretien ==
Afin de préserver au maximum le potentiel de végétalisation des façades, le mur doit conserver ses irrégularités, sans altérer l'état général de la surface. Faire grimper du lierre sur un mur dont les joints sont abîmés (joints sableux) peut être dommageable pour la surface.
L'entretien des façades ne peut pas se faire à toutes les époques de l'année afin de respecter les rythmes de la faune et de la flore qui y auront trouvé refuge. Il faut éviter les périodes de [[nidification]] ou les périodes de froid hivernal pendant lesquelles la végétation sert d'abri pour de nombreux [[invertébré]]s.
Afin de faciliter la [[végétalisation]] suivant un processus naturel, il faut conserver des îlots de végétation (mousse, fougères) lors de l'entretien des façades.
Une attention particulière doit être apportée à l’entretien des façades et structures végétalisées. Si les plantes grimpantes ou la flore des [[Toiture végétale|terrasses extensives]] sont rustiques et ne nécessitent ni arrosage ni engrais. Il faut respecter les points suivants :
*Les [[plante grimpante|plantes grimpantes]] ne doivent pas atteindre les tuiles, ardoises ni les [[Gouttière (architecture)|gouttière]]s. Si leurs feuilles mortes bouchaient ou freinaient l’évacuation des eaux pluviales, celles-ci pourraient déborder et s’écouler le long des façades, au risque d’altérer les matériaux, de favoriser la pénétration de racines et l'implantation de fougères, graminées, voire de plantes buissonnantes ou d'arbres dans les ciments de mauvaise qualité ou composés de chaux hydraulique naturelle, ou de terre.
**De la même façon, il faut tailler régulièrement les végétaux autour des ouvertures, prises d'air, cheminées, de manière que la végétation ne guide pas des espèces indésirables ou invasives vers les espaces intérieurs (insectes (comme les fourmis) ou araignées...). Un filtre de type moustiquaire peut protéger les prises d'air.
*Le pourtour des terrasses végétalisées doit être nettoyé ou inspecté une à 2 fois par an de manière à vérifier que les drains ne soient pas bouchés (par feuilles mortes, cadavres d'oiseaux, etc, ce qui vaut aussi pour les terrasses non végétalisées).
*Quelques plantes grimpantes, telles que la [[glycine (plante)|glycine]], peuvent s’enrouler autour des gouttières, des tuyauteries, et les compresser jusqu’à la rupture. Il faut donc contrôler, guider sélectionner ou adapter la végétalisation en fonction du type de mur ou de support.
Pour favoriser une [[biodiversité]] aussi proche que possible du potentiel local, toutes les surfaces du bâti, autres que les vitres et les panneaux solaires peuvent être végétalisées.
== Précautions, sécurité ==
[[Image:GlycineGouttière.jpg|thumb|right|300px|Une glycine enroulée sur une gouttière peut finir par la tordre ou l'écraser. Mieux vaut guider ce type de grimpante sur un support préparé pour elle.]]
L'aménageur doit prendre en compte les problèmes qui peuvent être posés par l'humidité (salissures par les spores de fougères, de mousses et de champignons, risques de court-circuit en cas d'éclairage artificiel, de chauffage, présence de pompes, etc.), et par le poids des végétaux qui grandissent.
Ces murs peuvent aussi être colonisés par une faune d'invertébrés tolérés ou souhaités en aquaterrarium, mais non désirés dans une habitation ou un lieu public.
Dans le cas de murs végétaux, le mur ou le support, s'ils ne sont pas conçus par l'architecte pour résister à l'eau enrichie de nutriments, doivent en être protégés.
Certains murs maçonnés à la terre ou à la chaux hydraulique doivent être protégés de la pénétration de racines susceptibles de les dégrader.
Un entretien et des vérifications régulières sont nécessaires.
En cas d'utilisation de plantes exotiques, afin d'éviter d'importer des organismes indésirables ou microbes pathogènes, il est recommandé de travailler avec des horticulteurs spécialisés et des plantes dont l'origine est traçable et légale.
== Les oiseaux ==
Le fait d'augmenter la biodiversité augmente aussi la présence des oiseaux. Or, les surfaces vitrées constituent un piège visuel pour l'avifaune qui percute des fenêtres de jour ou de nuit.
*L'oiseau peut être victime d'un effet miroir lorsque la vitre reflète le ciel.
*Il peut penser pouvoir traverser le bâtiment lorsqu'il aperçoit une autre ouverture dans le même axe.
*Il peut percuter une vitre invisible de type mur antibruit ou de type « balustrade vitrée » par exemple sur une terrasse.
*De nuit, l'oiseau en migration percute assez fréquemment la fenêtre d'une pièce éclairée, victime d'un des effets de la [[pollution lumineuse]].
**Dans ce dernier cas, la fréquence des collisions peut être diminuée de 80 % par la fermeture d'un volet ou d'un rideau épais.
**De jour, on diminue fortement le risque de collision par l'apposition d'une silhouette noire représentant un oiseau de proie, encore plus efficacement si celle-ci est suspendue à un fil qui lui permet de bouger. Ces silhouettes sont commercialisées par différentes associations ou institutions. Elles ne gênent pas la faune locale qui s'y habitue et préviennent les collisions avec les oiseaux migrateurs ou de passage.
== Variantes intérieures ==
Une variante à la façade végétalisée est le mur intérieur végétalisé.
La seule contrainte supplémentaire concerne la [[lumière]] qui doit être amenée en quantité et qualité suffisantes, et si possible orientée du haut vers le bas pour assurer une bonne croissance aux végétaux. Le mur végétalisé d'intérieur peut être construit dans une [[véranda]] ou sous une verrière, en prenant garde aux éventuelles surchauffes et aux problèmes éventuels liés à l'eau et à la condensation.
Une première manière de végétaliser le mur est de mettre sur la surface un substrat apte à être colonisé par les végétaux choisis. Ce substrat sera comparable à celui des toitures végétalisées, ou de type feutre synthétique associé à un système de pompe (éventuellement solaire) maintenant un écoulement d'eau le long du substrat qui sera progressivement colonisé par les végétaux qu'on y aura plantés.
Quelques exemples de réalisations intérieures innovantes :
<gallery>
Image:Bar végétalisé 2.JPG|<div style="text-align: center;">Bar végétalisé</div>
Image:Triptik.png|<div style="text-align: center;">Le tableau végétal</div>
Image:Mur végétal intérieur.jpg|<div style="text-align: center;">Un Mur intérieur</div>
</gallery>
{{message galerie}}
Il est aussi possible de planter des végétaux grimpants, buissonnants ou arbres dans le "vrai sol" ; Ainsi dans le lycée [[w:Haute qualité environnementale|HQE]] de Calais, des arbres ont été plantés sous les verrières intérieures, non dans des fosses qui nécessiterait un arrosage, mais dans le vrai sol réservé par l'architecte.
On peut aussi faire entrer le végétal (type lierre ou plante grimpante) par un orifice réservé en bas du mur, garni d'un isolant, tout en laissant ses racines s'épanouir dans le sol à l'extérieur. Les végétaux à crampons ou racines aériennes prennent appui sur la structure et colonisent progressivement le mur. Il faut cependant mettre en place un système permettant d'empêcher l'accès aux araignées, souris et autres indésirables par l'orifice d'accès du végétal. Ce système est le plus simple, car il ne nécessite quasiment pas d'entretien, si ce n'est une taille régulière pour éviter l'envahissement de la maison. En général, il n’est pas nécessaire de l'arroser puisque le végétal a ses racines à l'extérieur, sauf en cas de sécheresse prolongée.
L'intérêt principal du mur végétalisé peut être le [[w:renouvellement de l'air intérieur|renouvellement de l'air intérieur]] ou la [[w:phytoremédiation|phytoremédiation]]. Voir aussi le programme [[w:Phyt'air|Phyt'air]].
=== Le mobilier urbain végétalisé ===
[[Image:LierrePoteau.jpg|thumb|Poteau électrique et support de [[w:lampadaire|lampadaire]] couverts de lierre. <br />Sans remplacer un arbre, ce poteau rembourse une partie de sa [[w:Dette écologique|dette écologique]] en produisant de l'oxygène toute l'année et en offrant gîte et couvert aux oiseaux et à d'autres animaux.]]
Pour pallier le manque d'arbres et de photosynthèse en milieu urbain, une grande partie du mobilier urbain pourrait être végétalisé :
* [[w:Poteau électrique|Poteau électrique]] ;
* [[w:Lampadaire|Lampadaire]] ;
* [[w:Banc public|Banc public]] ;
* [[w:Abribus|Abribus]], etc.
Plusieurs solutions sont possibles : plantations directement dans le sol lorsque c'est possible (végétalisation auto-entretenue) ou dans des bacs de volume variable en fonction de la taille de la structure (il faut alors arroser le végétal régulièrement, au moins les premières années).
Les [[toiture végétale|toitures-terrasses végétalisées]] peuvent également compléter ces dispositifs, ne nécessitant que peu d'entretien s'il s'agit d'une végétalisation extensive ([[sédum]]s..).
==Prospective ==
L'objectif de stopper la perte de biodiversité en 2010 ou avant 2012 implique de contribuer à la restaurer partout où cela se peut, dont en ville et dans ou sur le bâti;
(début d'article, non terminé. Aide bienvenue)
{{...}}
==Bibliographie==
* Noël Dunnett ''Toits et murs végétaux'' ; Éd. du Rouergue, Rodez, 2008
* Jean-Michel Groult, ''Créer un mur végétal''/ Paris : Ulmer ; DL 2008
* Kindt, Agnes (Institut du Développement Durable et Responsable), Véronique DHAM (Gondwana), présentation ''[http://www.gecina.fr/fo/fileadmin/user_upload/Developpement%20durable/GECINALAB/2012/Horizons%20-Biodiversite-%2003%2004%2012.pdf La Biodiversité, semaine du développement durable]'', 3 avril 2012. IDDR Université catholique de Lille. Conférence Gecina
* Lewandowski, Delphine (2021) Étude et définition théoriques, techniques et biologiques d’un mur « biodiversitaire » – Un nouveau système de végétalisation vertical favorisant la biodiversité, thèse Paris Est, sous la direction de Robert Le Roy et Philippe Clergeau, www.theses.fr/s235700, en partenariat avec l’agence ChartierDalix, la plateforme Faire et le Pavillon de l’Arsenal, https://cesco.mnhn.fr/fr/actualites/un-mur-biodiversitaire-sinstalle-devant-le-laboratoire-6434.
==Notes et références pour ce sous-chapitre==
<references />
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|L'enveloppe du bâti elle-même ]]
ni9wru8dqw7helgp4w38vbjrjov0ou5
764233
764231
2026-04-21T14:57:58Z
Lamiot
1916
/* Le mur végétalisé */ complément sourcé sur les murs habités
764233
wikitext
text/x-wiki
[[Image:HK Kennedy Town Forbes Street w1.jpg|thumb|upright=1.5|Dans certaines conditions, la végétation - et ici son système racinaire - peut envelopper ou couvrir un mur ancien, en l’abîmant peu, voire en le protégeant (ici à [[Hongk-Hong]])]]
Diverses parties de l'enveloppe ou du support (poteaux, etc) d'une construction peuvent abriter ou faciliter la vie de nombreuses espèces d'animaux et végétaux, sans que cela nuise à la structure ou aux fonctions du bâti si ce dernier est conçu pour empêcher sa dégradation par la faune, la flore et les champignons, et pour empêcher les contacts directs entre la faune et les habitants ou usagers dans le cas de structures habitées.
==L'architecture traditionnelle==
[[File:Ruche pédagogiqueKCC2008Lamiot3.jpg|thumb|left|upright=1.3|Cette ruche "pédagogique" située dans un bâtiment (magasin et lieu de réunion) de l'ONG anglais [http://kentwildlife.smartchange.org/ Kent Wildlife trust] et KMRBC ([http://www.kmbrc.org.uk/aboutus/aboutKMBRC/index.php Kent & Medway Biological Records Centre]) (Kent, Royaume-Uni) permet de voir les abeilles au travers des vitres, d'écouter leur vrombissement, de sentir l'odeur de la ruche, grâce des orifices grillagés ; placée à l'ombre, elle communique avec l'extérieur via un conduit traversant le mur]]
[[File:Bee boles.jpg|thumb|upright=1|Niches dans un mur de brique, abritant des ruches traditionnelles (pour produire miel et cire), mais aussi utile pour polliniser les fruitiers proches (Lost Gardens of Heligan, Cornouaille, Royaume-Uni)]]
[[File:Beehivepubsign.jpg|thumb|upright=1|Enseigne anglaise faite d'une véritable ruche, habitée par des abeilles (Beehive Inn, Grantham, Royaume-Uni]]
* '''Concernant la flore''' : <br />Les toitures végétalisées semblent avoir été courantes et anciennes en Europe du nord.
<br />Des plantes grimpantes (lierre, vigne vierge, chèvre feuille ont également colonisé des murs de toutes sorte depuis longtemps en zone tempérée.
<br />En zone tropicale et équatoriale, la flore (très exubérante) est la faune sauvage sont au contraire maintenue à distance.
* '''Concernant la faune''' : <br />En Europe et Asie du nord, l'habitat humain, les fermes et les châteaux semblent - depuis les débuts de l'histoire de l'architecture - avoir accordé une large place à la faune domestiquée ;
<br />ainsi trouve-ton des traces anciennes de niches et chenils pour les chiens (chiens de garde ou de chasse), poulaillers, chatières... <br>Des écuries et étables adossées à la ferme, ou formant son rez de chaussée étaient fréquent dans le moyen-âge européen.
<br/>Des pigeonniers, voire des ruchers pouvaient être intégrés dans les murs, respectivement pour la récolte de fientes (comme engrais), d’œufs, la viande de pigeon et pour le miel et la cire).
<br />Plusieurs espèces d'hirondelles qui débarrassaient les étables et écuries des nuées de mouches attirées par les animaux et leur fumier sont devenues si proches de l'homme qu'on les caractérise souvent comme [[w:Commensal|commensale]]s de l'homme.
{{clear}}
==L'architecture contemporaine==
Certains architectes, dans les projets où la qualité environnementale est privilégiée, accordent depuis peu une place croissante à la flore, et commencent parfois à intégrer la faune sauvage dans leurs projets. Le concept de « maison-nichoir » a en France été promu par Jean-François Noblet (voir bibliographie)
==Le mur végétalisé==
Dans sa [https://theses.hal.science/tel-04536164 Thèse sur les'' murs biodiverses''] (murs ou parois conçus pour accueillir la biodiversité tout en contribuant à la régulation thermique des bâtiments), soutenue à l'Université Paris-Est, en 2023, Delphine Lewandowski présente la manière dont un réseau interne continu de substrat organique peut permettre l’installation durable du vivant, à certaines conditions. Elle a étudié :
:- le rôle et la gestion de l’eau dans un tel système vertical ;
:- l’installation et le maintien des plantes et du substrat ;
:- la biocompatibilité et ''bioréceptivité des matériaux'' (capacité à accueillir des organismes vivants) ;
:- la morphologie des murs (quantité, nature et qualité des interstices, des irrégularités, des volumes...).
Pour répondre à ces enjeux, D.Lewandowski a adopté une approche multidisciplinaire mêlant architecture, science des matériaux, écologie urbaine et science des sols, dans 3 expérimentations principales :
# Étude à l’échelle 1:1 de trois murs biodiversitaires maçonnés : <br>- Deux murs en briques d’argile cuite et un en pierre sèche ; <br>- Observation sur plusieurs saisons ; <br>- Facteurs influençant la biodiversité : orientation, hauteur, humidité, pH, densité, capacité thermique, albédo, morphologie ;<br>- Résultat : formulation de recommandations de conception.
# Analyse de la bioréceptivité des matériaux, évaluée par des expérimentations en serre avec deux plantes muricoles ; des tests sur trois bétons et une brique concassés, avec ou sans compost, avec comme résultat majeur que le pH du matériau et du substrat de croissance influencent fortement la croissance végétale
# Étude du comportement du substrat en verticalité, avec une analyse du tassement et de la teneur en eau du substrat selon sa granulométrie, qui montre la nécessité d’un substrat contenant une proportion élevée de gros grains rigides pour limiter le tassement et assurer une bonne répartition de l’eau.
== Histoire, réhabilitation historiques... ==
[[File:MoutonSoaySoaySheepUrbanGrazing2012LilleLamiotF 03.JPG|thumb|250px|[[w:fr:Mouton de Soay|Moutons de Soay]] utilisés pour la [[w:fr:Gestion restauratoire|gestion restauratoire]] de la végétation couvrant le sommet des murs d'une partie récemment restaurée des fortifications de la [[w:fr:Citadelle de Lille|Citadelle de Lille]]. Très à l'aise sur les pentes, cet animal remplace la tondeuse tout en jouant un rôle de ''[[w:fr:Corridor biologique|corridor écologique]] ambulant'' (il véhicule des [[w:fr:Graine|graine]]s et [[w:fr:Propagule|propagule]]s dans son pelage, son tube digestif et sous ses sabots)]]
[[File:Écomatériaux biodiversité construction Lille 2016 a Citadelle 8.JPG|thumb|left|upright=1.4|Sur une partie des fortifications (contre-garde), une expérimentation en faveur de la biodiversité doit permettre à quelques espèces végétales et animales « muricoles » (invertébrés, chauve-souris) de continuer à vivre sur le site, et faciliter leur observation par le public.<br /> Sur quelques dizaines de mètre des parpaings spéciaux ont été maçonnés avec de la terre, et remplis d'une terre compact (riche en argile et chaux). Les spores et graines sauvages adaptées au milieu sont apportées par le vent, les insectes, les oiseaux, etc. les espèces s'auto-sélectionnent et s'adaptent à ce microclimat particulier (chaud et sec en été, très exposé au vent).]]
[[File:Gabion terre pierre Citadelle Lille biodiversité 2016 Lamiot a.JPG|thumb|left|upright=1.4|Sur quelques mètres, et dans le même objectif que sur l'image ci-dessus, une autre expérience utiliser des [[w:gabion|gabions]] emplis de petites pierres calcaire dure et de terre.]]
La colonisation naturelle de murs et murets par des plantes (dont arbres) est naturelle.
Elle est habituellement considérée comme un problème, les racines endommageant les mortiers naturels de terre ou de chaux hydraulique naturelle, surtout s'ils sont souvent humides. Ces racines peuvent dans certaines conditions, décoller les briques ou encore favoriser l'humidité du mur (ou au contraire la drainer), ou augmenter sa vulnérabilité au gel (ex : cas des murs de fortification dont le cœur est constituée de pierre calcaire gélive, cachées sous un parement protecteur de pierre dure ou de brique). <br />En zone tropicale humide, certains arbres peuvent rapidement coloniser et entièrement recouvrir des architectures (dont patrimoniales telles que celles des temples d'[[w:fr:Angkor|Angkor]] en quelques siècles).
Des structures architectoniques artificielles, ciment ou appareils de pierres maçonnées, que l'on laisse volontairement se couvrir de [[w:Bryophyte|mousse]]s et de quelques plantes [[w:muricole|muricoles]] ([[w:Fougère|fougère]]s notamment) existent néanmoins (depuis plus de 200 ans au moins en France dans quelques grands parcs royaux ou municipaux, initialement toujours associés à des fontaines ou cascades).
Les "fabriques" romantiques (faux bâtiments anciens, fausses ruines) les ont beaucoup apprécié au XIXe siècle.
Ils ont ensuite été développés par certains [[w:zoo|zoos]] et pour le décor de [[w:fr:terrarium|terrarium]]s ou d'[[w:fr:aquaterrarium|aquaterrarium]]s publics ou privés, utilisant généralement des espèces tropicales en culture [[w:hydroponique|hydroponique]]<ref>http://jardin-botanique.ups-tlse.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1221657599742&ID_FICHE=68457 Fiche du Jardin botanique Henri Gaussen, présentant un mur végétal tropical élaboré par Patrick Blanc], pdf, 1 page </ref>, avant que le [[w:fr:Botaniste|botaniste]] et chercheur français [[w:fr:Patrick Blanc|Patrick Blanc]] ne crée, teste et développe son concept [[w:fr:horticulture|horticole]] de ''mur végétal'' sur support de feutre horticole.
D'autres techniques de murs végétaux se développent et dans leur sillage ou indépendamment, des designers et paysagistes ont développé de nouvelles méthodes et outils pour les espaces intérieurs. Des systèmes en kits prévégétalisés à assembler existent <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/technologie-de-realisation-du-mur-vegetal-et-du-jardin-vertical-greenwall.html Système de kits, de Greenwall Végétalis, conçu avec l'aide de scientifiques]</ref> ou de supports conçus avec l'aide de scientifique et d'un logiciel de modélisation de la croissance des plantes (croissance, aspect, couleur...) <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/mur-vegetal-et-jardin-vertical-vivant.html Voir la Animation 4D réalisée par l’ U.M.R A.M.A.P du CIRAD sur une suite logicielle (Orchestra®) de Bionatics.] (consulté 2010/30/08)</ref>, Fedor van der Valk a inventé de minis-jardins suspendus intérieurs (« ''String Gardens'' ») qui semblent flotter dans le vide en supportant des cascades de verdure. Le néo-zélandais Patrick Morris réussit à donner l'impression que le plafond est tapissé de plantes, via des jardinières à double fond qui y sont suspendues. L'équipe d'Amaury Gallon vient installer un mur végétal en kit, installé à domicile. Le designer Richard Grassin Delyle propose des cloisons ou doubles cloisons végétalisées, éventuellement mobiles, avec plantes fixées sur tissus horticole horizontal <ref>[http://www.mur-vegetal-interieur.fr/mur-vegetal.html Présentation des cloisons végétales de Richard Grassin Delyle] (avec réserve d'eau pour 3 à 4 semaines, mais nécessitant une prise électrique)</ref>. De nombreux exemples de murs intérieurs sont aujourd'hui disponibles<ref>[http://aquakarma974.over-blog.com/ Ex : Jardin vertical intérieur de 33 m3 d'Aquakarma 974]</ref>.
Le [[w:Gabion|gabionnage]] a encore donné lieu au XXème siècle à divers [[w:innovation|innovation]]s<ref>ex : CLAUZEL, L. (1963). ''[http://documents.irevues.inist.fr/bitstream/handle/2042/24557/RFF_1963_6_512.pdf?sequence=1? Un nouveau système de gabions: les coffres en treillis d'acier remplis en hérisson]''.</ref> et [[w:brevet (invention)|brevets]]<ref>ex : Hilfiker, W. K. (1991). U.S. Patent No. 5,076,735. Washington, DC: U.S. Patent and Trademark Office (brevet)</ref>, mais leur relative simplicité de fabrication peut permettre comme au [[Burkina Faso]] de les faire fabriquer par des artisans locaux<ref>Royet, P. (1992). Les ouvrages en gabions, [http://agris.fao.org/agris-search/search.do?recordID=FR19960033446 fiche Agris-FAO]</ref>. On a notamment essayé d'y intégrer des fonctions de [[services écosystémiques]] en les rendant parfois plus propices à la [[biodiversité]], par exemple en permettant leur colonisation par des [[w:racine|racine]]s d'[[w:racine|arbre]]s<ref>Koch, D. (1994). ''Essai d'intégration de la végétation dans les gabions sur un chantier de construction de route au Népal central'' (Doctoral dissertation).</ref>
{{clear}}
== Principe ==
[[File:04_-_Végétalis®_chevalets.jpg|thumb|upright=1|left|Des producteurs (ici ''murs végétalis®'') proposent des mélanges d'espèces et de variétés permettant une meilleure résistance aux maladies…]]
[[File:Greenbox®.jpg|thumb|250px|Module ''Greenbox®'']]
[[File:Végétalis® école archi.jpg|thumb|upright=1|Mur végétalis® de l'[[école d'architecture de Montpellier]], don de la société ''Greenwall'']]
[[File:03_-_Cultures_végétalis.jpg|thumb|upright=1|Les plantes préparées sur une surface presque verticale auront un aspect plus naturel dès leur installation sur le mur (Cultures végétalis®)]]
Des murs ou parois végétalisées peuvent être aménagés tant à l'extérieur qu'à l'intérieur de bâtiments, avec ou sans source artificielle de lumière.
<br>Le principe s'appuie sur le fait qu'en l'absence d'intervention humaine, en présence d'air propre et d'une humidité suffisante de l'air, tout support tend à être naturellement colonisé par des bactéries ([[biofilm]]), des [[algue]]s, puis des [[mousse (botanique)|mousse]]s et des [[lichen]]s, avant l'apparition de petites plantes, qui sont généralement aussi des épiphytes des arbres. Dans le cas où le mur reste sec, ou en atmosphère plus sèche, il peut également être colonisé par des plantes grimpantes ([[Lierre grimpant|lierre]], [[vigne vierge]] en [[climat tempéré]]).
<br>Plusieurs approches techniques existent, allant de l'insertion de plantes adaptées aux milieux secs et pauvres (crassulantes, cactées..) pour créer des structure de type ''« jardins de rocailles »'', à des techniques sophistiquées dites de "génie végétal" optimisant les conditions de colonisation et de pousse des plantes grâce à des supports de feutre synthétique dans lequel circule de l'eau enrichie en sels nutritifs.
Un grand nombre de plantes tropicales épiphytes ou poussant à l'ombre de la canopée se contentent de peu de lumière et de peu de nutriments.
== Types d'aménagement de façades ==
Il peut se faire soit à partir du sol directement, les racines de plantes grimpantes y puisant leur nourriture et l'eau, soit en intégrant la flore au bâtiment, via des balconnières, des jardinières, ou des systèmes plus complexe de murs végétaux tels que ceux de [[Patrick Blanc]].
'''Par exemple :''' Sur le mur porteur est placé une ossature métallique qui soutient une plaque de [[Chlorure de polyvinyle|PVC]] expansé de 10 mm d'épaisseur, sur laquelle sont agrafées deux couches de feutre de [[polyamide]] de 3 mm d'épaisseur chacune. Ces couches de feutre miment en quelque sorte les [[mousse (botanique)|mousse]]s qui se développent sur les parois rocheuses et qui servent de support aux [[Racine (botanique)|racines]] des plantes. Un réseau de tuyaux commandés par des électrovannes apporte une [[solution nutritive]] contenant les éléments minéraux nécessaires à la croissance des plantes. Le feutre s'imprègne de cette solution nutritive, qui redescend le long du mur par gravité. Les racines des plantes n'ont qu'à se servir, et l'eau en excès est recueillie en bas du mur par une gouttière, avant d'être réinjectée dans le réseau de tuyaux : le système fonctionne en circuit fermé.
C'est une variation inhabituelle d'une [[machine vivante]] : l'eau s'écoule sur une surface sur laquelle se développent de la [[mousse (botanique)|mousse]] ou d'autres plantes, quelques [[insecte]]s et des [[bactérie]]s, et est captée en bas du mur dans une [[Gouttière (architecture)|gouttière]], d'où elle est réinjectée en haut du mur.
== Les avantages ==
En plus de l'aspect esthétique, le mur végétalisé présente plusieurs avantages :
*Il permet une meilleure régulation thermique du bâtiment. En été, l'ensoleillement est réduit.
*L'[[w:évapotranspirationévapotranspiration]] du lierre ou d'autres grimpantes contribue au rafraîchissement de l'air et à une régulation de l'[[w:Hygrométrie|hygrométrie]]. En hiver, ce couvert végétal seul ne peut jouer un véritable rôle d'[[w:Isolation (construction)|isolant]], mais en asséchant les fondations et en protégeant les murs de la pluie (grâce à l'orientation des feuilles et à leur densité dans le cas du lierre), il les rend plus [[w:Isolant|isolant]]s.
*Il protège le bâtiment contre l'effet corrosif des pollutions urbaines ([[w:Pluie acide|pluie acide]], [[w:Pollution de l'air|pollution atmosphérique]]) et contre l’humidité (acide, en ville), en offrant une surface imperméable à la pluie. En effet, la disposition "en tuiles" des feuilles de certaines grimpantes, telles que le lierre, permet de protéger presque totalement le mur de la pluie.
*Les racines participent à l'assèchement du sol à proximité des fondations.
*La végétalisation des façades offre une surface végétale supplémentaire et significative pour l'épuration de l'air et la production d'oxygène.
*Certains [[w:mur anti-bruit|murs anti-bruit]] sont végétalisés, augmentant leur fonction dé-stressante (végétalis®, Le Prieuré, Héliotrope…). Le feuillage seul est réputé inefficace (une épaisseur de 10 m de feuillage d'arbres ne réduit un son puissant que d'à peine 1 dba), cependant le bruit du vent dans les feuilles et celui des oiseaux (comme celui des fontaines) ont des vertus psychologiquement apaisantes, et sans vraiment cacher le bruit ambiant, ils le rendent plus supportable.
== Utilisation du lierre ==
Le [[Lierre grimpant|lierre]] est une plante particulièrement bien adaptée au verdissement des façades. Sauf dans le cas de murs maçonnés à la [[Chaux (chimie)|Chaux hydraulique naturelle]] ou à la terre et qui seraient assez humides pour que les racines puissent y vivre, ce végétal n'abîme pas les façades, bien qu'il puisse endommager les peintures où ses crampons laissent des traces. Il est résistant aux conditions climatiques rudes ([[inondation]], gel, [[sécheresse]]...). Il reste vert toute l'année, ce qui lui permet de continuer à absorber du carbone pendant l'hiver, alors que la plupart des végétaux ont perdu leurs feuilles. La période de pollinisation du lierre se situe vers la fin de l'été. Il offre donc aux invertébrés pollinisateurs la possibilité de bénéficier d'un dernier approvisionnement en [[pollen]] avant l'hiver. Les fruits du lierre apparaissent très tôt dans l'année (vers le mois de mars), et constituent une nourriture de base pour les oiseaux frugivores, alors que leur nourriture fraîche commence à manquer. De plus, au même titre que certaines autres espèces indigènes ([[fougère]]s, [[cymbalaire]]), le lierre possède une valeur esthétique.
Les autres espèces couramment utilisées sont la [[vigne vierge]], le [[chèvrefeuille]]...
== Entretien ==
Afin de préserver au maximum le potentiel de végétalisation des façades, le mur doit conserver ses irrégularités, sans altérer l'état général de la surface. Faire grimper du lierre sur un mur dont les joints sont abîmés (joints sableux) peut être dommageable pour la surface.
L'entretien des façades ne peut pas se faire à toutes les époques de l'année afin de respecter les rythmes de la faune et de la flore qui y auront trouvé refuge. Il faut éviter les périodes de [[nidification]] ou les périodes de froid hivernal pendant lesquelles la végétation sert d'abri pour de nombreux [[invertébré]]s.
Afin de faciliter la [[végétalisation]] suivant un processus naturel, il faut conserver des îlots de végétation (mousse, fougères) lors de l'entretien des façades.
Une attention particulière doit être apportée à l’entretien des façades et structures végétalisées. Si les plantes grimpantes ou la flore des [[Toiture végétale|terrasses extensives]] sont rustiques et ne nécessitent ni arrosage ni engrais. Il faut respecter les points suivants :
*Les [[plante grimpante|plantes grimpantes]] ne doivent pas atteindre les tuiles, ardoises ni les [[Gouttière (architecture)|gouttière]]s. Si leurs feuilles mortes bouchaient ou freinaient l’évacuation des eaux pluviales, celles-ci pourraient déborder et s’écouler le long des façades, au risque d’altérer les matériaux, de favoriser la pénétration de racines et l'implantation de fougères, graminées, voire de plantes buissonnantes ou d'arbres dans les ciments de mauvaise qualité ou composés de chaux hydraulique naturelle, ou de terre.
**De la même façon, il faut tailler régulièrement les végétaux autour des ouvertures, prises d'air, cheminées, de manière que la végétation ne guide pas des espèces indésirables ou invasives vers les espaces intérieurs (insectes (comme les fourmis) ou araignées...). Un filtre de type moustiquaire peut protéger les prises d'air.
*Le pourtour des terrasses végétalisées doit être nettoyé ou inspecté une à 2 fois par an de manière à vérifier que les drains ne soient pas bouchés (par feuilles mortes, cadavres d'oiseaux, etc, ce qui vaut aussi pour les terrasses non végétalisées).
*Quelques plantes grimpantes, telles que la [[glycine (plante)|glycine]], peuvent s’enrouler autour des gouttières, des tuyauteries, et les compresser jusqu’à la rupture. Il faut donc contrôler, guider sélectionner ou adapter la végétalisation en fonction du type de mur ou de support.
Pour favoriser une [[biodiversité]] aussi proche que possible du potentiel local, toutes les surfaces du bâti, autres que les vitres et les panneaux solaires peuvent être végétalisées.
== Précautions, sécurité ==
[[Image:GlycineGouttière.jpg|thumb|right|300px|Une glycine enroulée sur une gouttière peut finir par la tordre ou l'écraser. Mieux vaut guider ce type de grimpante sur un support préparé pour elle.]]
L'aménageur doit prendre en compte les problèmes qui peuvent être posés par l'humidité (salissures par les spores de fougères, de mousses et de champignons, risques de court-circuit en cas d'éclairage artificiel, de chauffage, présence de pompes, etc.), et par le poids des végétaux qui grandissent.
Ces murs peuvent aussi être colonisés par une faune d'invertébrés tolérés ou souhaités en aquaterrarium, mais non désirés dans une habitation ou un lieu public.
Dans le cas de murs végétaux, le mur ou le support, s'ils ne sont pas conçus par l'architecte pour résister à l'eau enrichie de nutriments, doivent en être protégés.
Certains murs maçonnés à la terre ou à la chaux hydraulique doivent être protégés de la pénétration de racines susceptibles de les dégrader.
Un entretien et des vérifications régulières sont nécessaires.
En cas d'utilisation de plantes exotiques, afin d'éviter d'importer des organismes indésirables ou microbes pathogènes, il est recommandé de travailler avec des horticulteurs spécialisés et des plantes dont l'origine est traçable et légale.
== Les oiseaux ==
Le fait d'augmenter la biodiversité augmente aussi la présence des oiseaux. Or, les surfaces vitrées constituent un piège visuel pour l'avifaune qui percute des fenêtres de jour ou de nuit.
*L'oiseau peut être victime d'un effet miroir lorsque la vitre reflète le ciel.
*Il peut penser pouvoir traverser le bâtiment lorsqu'il aperçoit une autre ouverture dans le même axe.
*Il peut percuter une vitre invisible de type mur antibruit ou de type « balustrade vitrée » par exemple sur une terrasse.
*De nuit, l'oiseau en migration percute assez fréquemment la fenêtre d'une pièce éclairée, victime d'un des effets de la [[pollution lumineuse]].
**Dans ce dernier cas, la fréquence des collisions peut être diminuée de 80 % par la fermeture d'un volet ou d'un rideau épais.
**De jour, on diminue fortement le risque de collision par l'apposition d'une silhouette noire représentant un oiseau de proie, encore plus efficacement si celle-ci est suspendue à un fil qui lui permet de bouger. Ces silhouettes sont commercialisées par différentes associations ou institutions. Elles ne gênent pas la faune locale qui s'y habitue et préviennent les collisions avec les oiseaux migrateurs ou de passage.
== Variantes intérieures ==
Une variante à la façade végétalisée est le mur intérieur végétalisé.
La seule contrainte supplémentaire concerne la [[lumière]] qui doit être amenée en quantité et qualité suffisantes, et si possible orientée du haut vers le bas pour assurer une bonne croissance aux végétaux. Le mur végétalisé d'intérieur peut être construit dans une [[véranda]] ou sous une verrière, en prenant garde aux éventuelles surchauffes et aux problèmes éventuels liés à l'eau et à la condensation.
Une première manière de végétaliser le mur est de mettre sur la surface un substrat apte à être colonisé par les végétaux choisis. Ce substrat sera comparable à celui des toitures végétalisées, ou de type feutre synthétique associé à un système de pompe (éventuellement solaire) maintenant un écoulement d'eau le long du substrat qui sera progressivement colonisé par les végétaux qu'on y aura plantés.
Quelques exemples de réalisations intérieures innovantes :
<gallery>
Image:Bar végétalisé 2.JPG|<div style="text-align: center;">Bar végétalisé</div>
Image:Triptik.png|<div style="text-align: center;">Le tableau végétal</div>
Image:Mur végétal intérieur.jpg|<div style="text-align: center;">Un Mur intérieur</div>
</gallery>
{{message galerie}}
Il est aussi possible de planter des végétaux grimpants, buissonnants ou arbres dans le "vrai sol" ; Ainsi dans le lycée [[w:Haute qualité environnementale|HQE]] de Calais, des arbres ont été plantés sous les verrières intérieures, non dans des fosses qui nécessiterait un arrosage, mais dans le vrai sol réservé par l'architecte.
On peut aussi faire entrer le végétal (type lierre ou plante grimpante) par un orifice réservé en bas du mur, garni d'un isolant, tout en laissant ses racines s'épanouir dans le sol à l'extérieur. Les végétaux à crampons ou racines aériennes prennent appui sur la structure et colonisent progressivement le mur. Il faut cependant mettre en place un système permettant d'empêcher l'accès aux araignées, souris et autres indésirables par l'orifice d'accès du végétal. Ce système est le plus simple, car il ne nécessite quasiment pas d'entretien, si ce n'est une taille régulière pour éviter l'envahissement de la maison. En général, il n’est pas nécessaire de l'arroser puisque le végétal a ses racines à l'extérieur, sauf en cas de sécheresse prolongée.
L'intérêt principal du mur végétalisé peut être le [[w:renouvellement de l'air intérieur|renouvellement de l'air intérieur]] ou la [[w:phytoremédiation|phytoremédiation]]. Voir aussi le programme [[w:Phyt'air|Phyt'air]].
=== Le mobilier urbain végétalisé ===
[[Image:LierrePoteau.jpg|thumb|Poteau électrique et support de [[w:lampadaire|lampadaire]] couverts de lierre. <br />Sans remplacer un arbre, ce poteau rembourse une partie de sa [[w:Dette écologique|dette écologique]] en produisant de l'oxygène toute l'année et en offrant gîte et couvert aux oiseaux et à d'autres animaux.]]
Pour pallier le manque d'arbres et de photosynthèse en milieu urbain, une grande partie du mobilier urbain pourrait être végétalisé :
* [[w:Poteau électrique|Poteau électrique]] ;
* [[w:Lampadaire|Lampadaire]] ;
* [[w:Banc public|Banc public]] ;
* [[w:Abribus|Abribus]], etc.
Plusieurs solutions sont possibles : plantations directement dans le sol lorsque c'est possible (végétalisation auto-entretenue) ou dans des bacs de volume variable en fonction de la taille de la structure (il faut alors arroser le végétal régulièrement, au moins les premières années).
Les [[toiture végétale|toitures-terrasses végétalisées]] peuvent également compléter ces dispositifs, ne nécessitant que peu d'entretien s'il s'agit d'une végétalisation extensive ([[sédum]]s..).
==Prospective ==
L'objectif de stopper la perte de biodiversité en 2010 ou avant 2012 implique de contribuer à la restaurer partout où cela se peut, dont en ville et dans ou sur le bâti;
(début d'article, non terminé. Aide bienvenue)
{{...}}
==Bibliographie==
* Noël Dunnett ''Toits et murs végétaux'' ; Éd. du Rouergue, Rodez, 2008
* Jean-Michel Groult, ''Créer un mur végétal''/ Paris : Ulmer ; DL 2008
* Kindt, Agnes (Institut du Développement Durable et Responsable), Véronique DHAM (Gondwana), présentation ''[http://www.gecina.fr/fo/fileadmin/user_upload/Developpement%20durable/GECINALAB/2012/Horizons%20-Biodiversite-%2003%2004%2012.pdf La Biodiversité, semaine du développement durable]'', 3 avril 2012. IDDR Université catholique de Lille. Conférence Gecina
* Lewandowski, Delphine (2021) Étude et définition théoriques, techniques et biologiques d’un mur « biodiversitaire » – Un nouveau système de végétalisation vertical favorisant la biodiversité, thèse Paris Est, sous la direction de Robert Le Roy et Philippe Clergeau, www.theses.fr/s235700, en partenariat avec l’agence ChartierDalix, la plateforme Faire et le Pavillon de l’Arsenal, https://cesco.mnhn.fr/fr/actualites/un-mur-biodiversitaire-sinstalle-devant-le-laboratoire-6434.
==Notes et références pour ce sous-chapitre==
<references />
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|L'enveloppe du bâti elle-même ]]
gwu137tv7x8aicft0aheo7bmehf7rpb
764234
764233
2026-04-21T15:00:28Z
Lamiot
1916
/* Utilisation du lierre */
764234
wikitext
text/x-wiki
[[Image:HK Kennedy Town Forbes Street w1.jpg|thumb|upright=1.5|Dans certaines conditions, la végétation - et ici son système racinaire - peut envelopper ou couvrir un mur ancien, en l’abîmant peu, voire en le protégeant (ici à [[Hongk-Hong]])]]
Diverses parties de l'enveloppe ou du support (poteaux, etc) d'une construction peuvent abriter ou faciliter la vie de nombreuses espèces d'animaux et végétaux, sans que cela nuise à la structure ou aux fonctions du bâti si ce dernier est conçu pour empêcher sa dégradation par la faune, la flore et les champignons, et pour empêcher les contacts directs entre la faune et les habitants ou usagers dans le cas de structures habitées.
==L'architecture traditionnelle==
[[File:Ruche pédagogiqueKCC2008Lamiot3.jpg|thumb|left|upright=1.3|Cette ruche "pédagogique" située dans un bâtiment (magasin et lieu de réunion) de l'ONG anglais [http://kentwildlife.smartchange.org/ Kent Wildlife trust] et KMRBC ([http://www.kmbrc.org.uk/aboutus/aboutKMBRC/index.php Kent & Medway Biological Records Centre]) (Kent, Royaume-Uni) permet de voir les abeilles au travers des vitres, d'écouter leur vrombissement, de sentir l'odeur de la ruche, grâce des orifices grillagés ; placée à l'ombre, elle communique avec l'extérieur via un conduit traversant le mur]]
[[File:Bee boles.jpg|thumb|upright=1|Niches dans un mur de brique, abritant des ruches traditionnelles (pour produire miel et cire), mais aussi utile pour polliniser les fruitiers proches (Lost Gardens of Heligan, Cornouaille, Royaume-Uni)]]
[[File:Beehivepubsign.jpg|thumb|upright=1|Enseigne anglaise faite d'une véritable ruche, habitée par des abeilles (Beehive Inn, Grantham, Royaume-Uni]]
* '''Concernant la flore''' : <br />Les toitures végétalisées semblent avoir été courantes et anciennes en Europe du nord.
<br />Des plantes grimpantes (lierre, vigne vierge, chèvre feuille ont également colonisé des murs de toutes sorte depuis longtemps en zone tempérée.
<br />En zone tropicale et équatoriale, la flore (très exubérante) est la faune sauvage sont au contraire maintenue à distance.
* '''Concernant la faune''' : <br />En Europe et Asie du nord, l'habitat humain, les fermes et les châteaux semblent - depuis les débuts de l'histoire de l'architecture - avoir accordé une large place à la faune domestiquée ;
<br />ainsi trouve-ton des traces anciennes de niches et chenils pour les chiens (chiens de garde ou de chasse), poulaillers, chatières... <br>Des écuries et étables adossées à la ferme, ou formant son rez de chaussée étaient fréquent dans le moyen-âge européen.
<br/>Des pigeonniers, voire des ruchers pouvaient être intégrés dans les murs, respectivement pour la récolte de fientes (comme engrais), d’œufs, la viande de pigeon et pour le miel et la cire).
<br />Plusieurs espèces d'hirondelles qui débarrassaient les étables et écuries des nuées de mouches attirées par les animaux et leur fumier sont devenues si proches de l'homme qu'on les caractérise souvent comme [[w:Commensal|commensale]]s de l'homme.
{{clear}}
==L'architecture contemporaine==
Certains architectes, dans les projets où la qualité environnementale est privilégiée, accordent depuis peu une place croissante à la flore, et commencent parfois à intégrer la faune sauvage dans leurs projets. Le concept de « maison-nichoir » a en France été promu par Jean-François Noblet (voir bibliographie)
==Le mur végétalisé==
Dans sa [https://theses.hal.science/tel-04536164 Thèse sur les'' murs biodiverses''] (murs ou parois conçus pour accueillir la biodiversité tout en contribuant à la régulation thermique des bâtiments), soutenue à l'Université Paris-Est, en 2023, Delphine Lewandowski présente la manière dont un réseau interne continu de substrat organique peut permettre l’installation durable du vivant, à certaines conditions. Elle a étudié :
:- le rôle et la gestion de l’eau dans un tel système vertical ;
:- l’installation et le maintien des plantes et du substrat ;
:- la biocompatibilité et ''bioréceptivité des matériaux'' (capacité à accueillir des organismes vivants) ;
:- la morphologie des murs (quantité, nature et qualité des interstices, des irrégularités, des volumes...).
Pour répondre à ces enjeux, D.Lewandowski a adopté une approche multidisciplinaire mêlant architecture, science des matériaux, écologie urbaine et science des sols, dans 3 expérimentations principales :
# Étude à l’échelle 1:1 de trois murs biodiversitaires maçonnés : <br>- Deux murs en briques d’argile cuite et un en pierre sèche ; <br>- Observation sur plusieurs saisons ; <br>- Facteurs influençant la biodiversité : orientation, hauteur, humidité, pH, densité, capacité thermique, albédo, morphologie ;<br>- Résultat : formulation de recommandations de conception.
# Analyse de la bioréceptivité des matériaux, évaluée par des expérimentations en serre avec deux plantes muricoles ; des tests sur trois bétons et une brique concassés, avec ou sans compost, avec comme résultat majeur que le pH du matériau et du substrat de croissance influencent fortement la croissance végétale
# Étude du comportement du substrat en verticalité, avec une analyse du tassement et de la teneur en eau du substrat selon sa granulométrie, qui montre la nécessité d’un substrat contenant une proportion élevée de gros grains rigides pour limiter le tassement et assurer une bonne répartition de l’eau.
== Histoire, réhabilitation historiques... ==
[[File:MoutonSoaySoaySheepUrbanGrazing2012LilleLamiotF 03.JPG|thumb|250px|[[w:fr:Mouton de Soay|Moutons de Soay]] utilisés pour la [[w:fr:Gestion restauratoire|gestion restauratoire]] de la végétation couvrant le sommet des murs d'une partie récemment restaurée des fortifications de la [[w:fr:Citadelle de Lille|Citadelle de Lille]]. Très à l'aise sur les pentes, cet animal remplace la tondeuse tout en jouant un rôle de ''[[w:fr:Corridor biologique|corridor écologique]] ambulant'' (il véhicule des [[w:fr:Graine|graine]]s et [[w:fr:Propagule|propagule]]s dans son pelage, son tube digestif et sous ses sabots)]]
[[File:Écomatériaux biodiversité construction Lille 2016 a Citadelle 8.JPG|thumb|left|upright=1.4|Sur une partie des fortifications (contre-garde), une expérimentation en faveur de la biodiversité doit permettre à quelques espèces végétales et animales « muricoles » (invertébrés, chauve-souris) de continuer à vivre sur le site, et faciliter leur observation par le public.<br /> Sur quelques dizaines de mètre des parpaings spéciaux ont été maçonnés avec de la terre, et remplis d'une terre compact (riche en argile et chaux). Les spores et graines sauvages adaptées au milieu sont apportées par le vent, les insectes, les oiseaux, etc. les espèces s'auto-sélectionnent et s'adaptent à ce microclimat particulier (chaud et sec en été, très exposé au vent).]]
[[File:Gabion terre pierre Citadelle Lille biodiversité 2016 Lamiot a.JPG|thumb|left|upright=1.4|Sur quelques mètres, et dans le même objectif que sur l'image ci-dessus, une autre expérience utiliser des [[w:gabion|gabions]] emplis de petites pierres calcaire dure et de terre.]]
La colonisation naturelle de murs et murets par des plantes (dont arbres) est naturelle.
Elle est habituellement considérée comme un problème, les racines endommageant les mortiers naturels de terre ou de chaux hydraulique naturelle, surtout s'ils sont souvent humides. Ces racines peuvent dans certaines conditions, décoller les briques ou encore favoriser l'humidité du mur (ou au contraire la drainer), ou augmenter sa vulnérabilité au gel (ex : cas des murs de fortification dont le cœur est constituée de pierre calcaire gélive, cachées sous un parement protecteur de pierre dure ou de brique). <br />En zone tropicale humide, certains arbres peuvent rapidement coloniser et entièrement recouvrir des architectures (dont patrimoniales telles que celles des temples d'[[w:fr:Angkor|Angkor]] en quelques siècles).
Des structures architectoniques artificielles, ciment ou appareils de pierres maçonnées, que l'on laisse volontairement se couvrir de [[w:Bryophyte|mousse]]s et de quelques plantes [[w:muricole|muricoles]] ([[w:Fougère|fougère]]s notamment) existent néanmoins (depuis plus de 200 ans au moins en France dans quelques grands parcs royaux ou municipaux, initialement toujours associés à des fontaines ou cascades).
Les "fabriques" romantiques (faux bâtiments anciens, fausses ruines) les ont beaucoup apprécié au XIXe siècle.
Ils ont ensuite été développés par certains [[w:zoo|zoos]] et pour le décor de [[w:fr:terrarium|terrarium]]s ou d'[[w:fr:aquaterrarium|aquaterrarium]]s publics ou privés, utilisant généralement des espèces tropicales en culture [[w:hydroponique|hydroponique]]<ref>http://jardin-botanique.ups-tlse.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1221657599742&ID_FICHE=68457 Fiche du Jardin botanique Henri Gaussen, présentant un mur végétal tropical élaboré par Patrick Blanc], pdf, 1 page </ref>, avant que le [[w:fr:Botaniste|botaniste]] et chercheur français [[w:fr:Patrick Blanc|Patrick Blanc]] ne crée, teste et développe son concept [[w:fr:horticulture|horticole]] de ''mur végétal'' sur support de feutre horticole.
D'autres techniques de murs végétaux se développent et dans leur sillage ou indépendamment, des designers et paysagistes ont développé de nouvelles méthodes et outils pour les espaces intérieurs. Des systèmes en kits prévégétalisés à assembler existent <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/technologie-de-realisation-du-mur-vegetal-et-du-jardin-vertical-greenwall.html Système de kits, de Greenwall Végétalis, conçu avec l'aide de scientifiques]</ref> ou de supports conçus avec l'aide de scientifique et d'un logiciel de modélisation de la croissance des plantes (croissance, aspect, couleur...) <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/mur-vegetal-et-jardin-vertical-vivant.html Voir la Animation 4D réalisée par l’ U.M.R A.M.A.P du CIRAD sur une suite logicielle (Orchestra®) de Bionatics.] (consulté 2010/30/08)</ref>, Fedor van der Valk a inventé de minis-jardins suspendus intérieurs (« ''String Gardens'' ») qui semblent flotter dans le vide en supportant des cascades de verdure. Le néo-zélandais Patrick Morris réussit à donner l'impression que le plafond est tapissé de plantes, via des jardinières à double fond qui y sont suspendues. L'équipe d'Amaury Gallon vient installer un mur végétal en kit, installé à domicile. Le designer Richard Grassin Delyle propose des cloisons ou doubles cloisons végétalisées, éventuellement mobiles, avec plantes fixées sur tissus horticole horizontal <ref>[http://www.mur-vegetal-interieur.fr/mur-vegetal.html Présentation des cloisons végétales de Richard Grassin Delyle] (avec réserve d'eau pour 3 à 4 semaines, mais nécessitant une prise électrique)</ref>. De nombreux exemples de murs intérieurs sont aujourd'hui disponibles<ref>[http://aquakarma974.over-blog.com/ Ex : Jardin vertical intérieur de 33 m3 d'Aquakarma 974]</ref>.
Le [[w:Gabion|gabionnage]] a encore donné lieu au XXème siècle à divers [[w:innovation|innovation]]s<ref>ex : CLAUZEL, L. (1963). ''[http://documents.irevues.inist.fr/bitstream/handle/2042/24557/RFF_1963_6_512.pdf?sequence=1? Un nouveau système de gabions: les coffres en treillis d'acier remplis en hérisson]''.</ref> et [[w:brevet (invention)|brevets]]<ref>ex : Hilfiker, W. K. (1991). U.S. Patent No. 5,076,735. Washington, DC: U.S. Patent and Trademark Office (brevet)</ref>, mais leur relative simplicité de fabrication peut permettre comme au [[Burkina Faso]] de les faire fabriquer par des artisans locaux<ref>Royet, P. (1992). Les ouvrages en gabions, [http://agris.fao.org/agris-search/search.do?recordID=FR19960033446 fiche Agris-FAO]</ref>. On a notamment essayé d'y intégrer des fonctions de [[services écosystémiques]] en les rendant parfois plus propices à la [[biodiversité]], par exemple en permettant leur colonisation par des [[w:racine|racine]]s d'[[w:racine|arbre]]s<ref>Koch, D. (1994). ''Essai d'intégration de la végétation dans les gabions sur un chantier de construction de route au Népal central'' (Doctoral dissertation).</ref>
{{clear}}
== Principe ==
[[File:04_-_Végétalis®_chevalets.jpg|thumb|upright=1|left|Des producteurs (ici ''murs végétalis®'') proposent des mélanges d'espèces et de variétés permettant une meilleure résistance aux maladies…]]
[[File:Greenbox®.jpg|thumb|250px|Module ''Greenbox®'']]
[[File:Végétalis® école archi.jpg|thumb|upright=1|Mur végétalis® de l'[[école d'architecture de Montpellier]], don de la société ''Greenwall'']]
[[File:03_-_Cultures_végétalis.jpg|thumb|upright=1|Les plantes préparées sur une surface presque verticale auront un aspect plus naturel dès leur installation sur le mur (Cultures végétalis®)]]
Des murs ou parois végétalisées peuvent être aménagés tant à l'extérieur qu'à l'intérieur de bâtiments, avec ou sans source artificielle de lumière.
<br>Le principe s'appuie sur le fait qu'en l'absence d'intervention humaine, en présence d'air propre et d'une humidité suffisante de l'air, tout support tend à être naturellement colonisé par des bactéries ([[biofilm]]), des [[algue]]s, puis des [[mousse (botanique)|mousse]]s et des [[lichen]]s, avant l'apparition de petites plantes, qui sont généralement aussi des épiphytes des arbres. Dans le cas où le mur reste sec, ou en atmosphère plus sèche, il peut également être colonisé par des plantes grimpantes ([[Lierre grimpant|lierre]], [[vigne vierge]] en [[climat tempéré]]).
<br>Plusieurs approches techniques existent, allant de l'insertion de plantes adaptées aux milieux secs et pauvres (crassulantes, cactées..) pour créer des structure de type ''« jardins de rocailles »'', à des techniques sophistiquées dites de "génie végétal" optimisant les conditions de colonisation et de pousse des plantes grâce à des supports de feutre synthétique dans lequel circule de l'eau enrichie en sels nutritifs.
Un grand nombre de plantes tropicales épiphytes ou poussant à l'ombre de la canopée se contentent de peu de lumière et de peu de nutriments.
== Types d'aménagement de façades ==
Il peut se faire soit à partir du sol directement, les racines de plantes grimpantes y puisant leur nourriture et l'eau, soit en intégrant la flore au bâtiment, via des balconnières, des jardinières, ou des systèmes plus complexe de murs végétaux tels que ceux de [[Patrick Blanc]].
'''Par exemple :''' Sur le mur porteur est placé une ossature métallique qui soutient une plaque de [[Chlorure de polyvinyle|PVC]] expansé de 10 mm d'épaisseur, sur laquelle sont agrafées deux couches de feutre de [[polyamide]] de 3 mm d'épaisseur chacune. Ces couches de feutre miment en quelque sorte les [[mousse (botanique)|mousse]]s qui se développent sur les parois rocheuses et qui servent de support aux [[Racine (botanique)|racines]] des plantes. Un réseau de tuyaux commandés par des électrovannes apporte une [[solution nutritive]] contenant les éléments minéraux nécessaires à la croissance des plantes. Le feutre s'imprègne de cette solution nutritive, qui redescend le long du mur par gravité. Les racines des plantes n'ont qu'à se servir, et l'eau en excès est recueillie en bas du mur par une gouttière, avant d'être réinjectée dans le réseau de tuyaux : le système fonctionne en circuit fermé.
C'est une variation inhabituelle d'une [[machine vivante]] : l'eau s'écoule sur une surface sur laquelle se développent de la [[mousse (botanique)|mousse]] ou d'autres plantes, quelques [[insecte]]s et des [[bactérie]]s, et est captée en bas du mur dans une [[Gouttière (architecture)|gouttière]], d'où elle est réinjectée en haut du mur.
== Les avantages ==
En plus de l'aspect esthétique, le mur végétalisé présente plusieurs avantages :
*Il permet une meilleure régulation thermique du bâtiment. En été, l'ensoleillement est réduit.
*L'[[w:évapotranspirationévapotranspiration]] du lierre ou d'autres grimpantes contribue au rafraîchissement de l'air et à une régulation de l'[[w:Hygrométrie|hygrométrie]]. En hiver, ce couvert végétal seul ne peut jouer un véritable rôle d'[[w:Isolation (construction)|isolant]], mais en asséchant les fondations et en protégeant les murs de la pluie (grâce à l'orientation des feuilles et à leur densité dans le cas du lierre), il les rend plus [[w:Isolant|isolant]]s.
*Il protège le bâtiment contre l'effet corrosif des pollutions urbaines ([[w:Pluie acide|pluie acide]], [[w:Pollution de l'air|pollution atmosphérique]]) et contre l’humidité (acide, en ville), en offrant une surface imperméable à la pluie. En effet, la disposition "en tuiles" des feuilles de certaines grimpantes, telles que le lierre, permet de protéger presque totalement le mur de la pluie.
*Les racines participent à l'assèchement du sol à proximité des fondations.
*La végétalisation des façades offre une surface végétale supplémentaire et significative pour l'épuration de l'air et la production d'oxygène.
*Certains [[w:mur anti-bruit|murs anti-bruit]] sont végétalisés, augmentant leur fonction dé-stressante (végétalis®, Le Prieuré, Héliotrope…). Le feuillage seul est réputé inefficace (une épaisseur de 10 m de feuillage d'arbres ne réduit un son puissant que d'à peine 1 dba), cependant le bruit du vent dans les feuilles et celui des oiseaux (comme celui des fontaines) ont des vertus psychologiquement apaisantes, et sans vraiment cacher le bruit ambiant, ils le rendent plus supportable.
== Utilisation du lierre ==
Le [[w:fr:Lierre grimpant|lierre]] est une plante particulièrement bien adaptée au verdissement des façades. Sauf dans le cas de murs maçonnés à la [[w:fr:Chaux (chimie)|Chaux hydraulique naturelle]] ou à la terre et qui seraient assez humides pour que les racines puissent y vivre, ce végétal n'abîme pas les façades, bien qu'il puisse endommager les peintures où ses crampons laissent des traces. Il est résistant aux conditions climatiques rudes ([[w:fr:inondation|inondation]], gel, [[w:fr:sécheresse|sécheresse]]...). Il reste vert toute l'année, ce qui lui permet de continuer à absorber du carbone pendant l'hiver, alors que la plupart des végétaux ont perdu leurs feuilles. La période de pollinisation du lierre se situe vers la fin de l'été. Il offre donc aux invertébrés pollinisateurs la possibilité de bénéficier d'un dernier approvisionnement en [[w:fr:Pollen|pollen]] avant l'hiver. Les fruits du lierre apparaissent très tôt dans l'année (vers le mois de mars), et constituent une nourriture de base pour les oiseaux frugivores, alors que leur nourriture fraîche commence à manquer. De plus, au même titre que certaines autres espèces indigènes ([[w:fr:Fougère|fougère]]s, [[w:fr:Cymbalaire|cymbalaire]]), le lierre possède une valeur esthétique.
Les autres espèces couramment utilisées sont la [[w:fr:Vigne vierge|vigne vierge]], le [[w:fr:Chèvrefeuille|chèvrefeuille]]...
== Entretien ==
Afin de préserver au maximum le potentiel de végétalisation des façades, le mur doit conserver ses irrégularités, sans altérer l'état général de la surface. Faire grimper du lierre sur un mur dont les joints sont abîmés (joints sableux) peut être dommageable pour la surface.
L'entretien des façades ne peut pas se faire à toutes les époques de l'année afin de respecter les rythmes de la faune et de la flore qui y auront trouvé refuge. Il faut éviter les périodes de [[nidification]] ou les périodes de froid hivernal pendant lesquelles la végétation sert d'abri pour de nombreux [[invertébré]]s.
Afin de faciliter la [[végétalisation]] suivant un processus naturel, il faut conserver des îlots de végétation (mousse, fougères) lors de l'entretien des façades.
Une attention particulière doit être apportée à l’entretien des façades et structures végétalisées. Si les plantes grimpantes ou la flore des [[Toiture végétale|terrasses extensives]] sont rustiques et ne nécessitent ni arrosage ni engrais. Il faut respecter les points suivants :
*Les [[plante grimpante|plantes grimpantes]] ne doivent pas atteindre les tuiles, ardoises ni les [[Gouttière (architecture)|gouttière]]s. Si leurs feuilles mortes bouchaient ou freinaient l’évacuation des eaux pluviales, celles-ci pourraient déborder et s’écouler le long des façades, au risque d’altérer les matériaux, de favoriser la pénétration de racines et l'implantation de fougères, graminées, voire de plantes buissonnantes ou d'arbres dans les ciments de mauvaise qualité ou composés de chaux hydraulique naturelle, ou de terre.
**De la même façon, il faut tailler régulièrement les végétaux autour des ouvertures, prises d'air, cheminées, de manière que la végétation ne guide pas des espèces indésirables ou invasives vers les espaces intérieurs (insectes (comme les fourmis) ou araignées...). Un filtre de type moustiquaire peut protéger les prises d'air.
*Le pourtour des terrasses végétalisées doit être nettoyé ou inspecté une à 2 fois par an de manière à vérifier que les drains ne soient pas bouchés (par feuilles mortes, cadavres d'oiseaux, etc, ce qui vaut aussi pour les terrasses non végétalisées).
*Quelques plantes grimpantes, telles que la [[glycine (plante)|glycine]], peuvent s’enrouler autour des gouttières, des tuyauteries, et les compresser jusqu’à la rupture. Il faut donc contrôler, guider sélectionner ou adapter la végétalisation en fonction du type de mur ou de support.
Pour favoriser une [[biodiversité]] aussi proche que possible du potentiel local, toutes les surfaces du bâti, autres que les vitres et les panneaux solaires peuvent être végétalisées.
== Précautions, sécurité ==
[[Image:GlycineGouttière.jpg|thumb|right|300px|Une glycine enroulée sur une gouttière peut finir par la tordre ou l'écraser. Mieux vaut guider ce type de grimpante sur un support préparé pour elle.]]
L'aménageur doit prendre en compte les problèmes qui peuvent être posés par l'humidité (salissures par les spores de fougères, de mousses et de champignons, risques de court-circuit en cas d'éclairage artificiel, de chauffage, présence de pompes, etc.), et par le poids des végétaux qui grandissent.
Ces murs peuvent aussi être colonisés par une faune d'invertébrés tolérés ou souhaités en aquaterrarium, mais non désirés dans une habitation ou un lieu public.
Dans le cas de murs végétaux, le mur ou le support, s'ils ne sont pas conçus par l'architecte pour résister à l'eau enrichie de nutriments, doivent en être protégés.
Certains murs maçonnés à la terre ou à la chaux hydraulique doivent être protégés de la pénétration de racines susceptibles de les dégrader.
Un entretien et des vérifications régulières sont nécessaires.
En cas d'utilisation de plantes exotiques, afin d'éviter d'importer des organismes indésirables ou microbes pathogènes, il est recommandé de travailler avec des horticulteurs spécialisés et des plantes dont l'origine est traçable et légale.
== Les oiseaux ==
Le fait d'augmenter la biodiversité augmente aussi la présence des oiseaux. Or, les surfaces vitrées constituent un piège visuel pour l'avifaune qui percute des fenêtres de jour ou de nuit.
*L'oiseau peut être victime d'un effet miroir lorsque la vitre reflète le ciel.
*Il peut penser pouvoir traverser le bâtiment lorsqu'il aperçoit une autre ouverture dans le même axe.
*Il peut percuter une vitre invisible de type mur antibruit ou de type « balustrade vitrée » par exemple sur une terrasse.
*De nuit, l'oiseau en migration percute assez fréquemment la fenêtre d'une pièce éclairée, victime d'un des effets de la [[pollution lumineuse]].
**Dans ce dernier cas, la fréquence des collisions peut être diminuée de 80 % par la fermeture d'un volet ou d'un rideau épais.
**De jour, on diminue fortement le risque de collision par l'apposition d'une silhouette noire représentant un oiseau de proie, encore plus efficacement si celle-ci est suspendue à un fil qui lui permet de bouger. Ces silhouettes sont commercialisées par différentes associations ou institutions. Elles ne gênent pas la faune locale qui s'y habitue et préviennent les collisions avec les oiseaux migrateurs ou de passage.
== Variantes intérieures ==
Une variante à la façade végétalisée est le mur intérieur végétalisé.
La seule contrainte supplémentaire concerne la [[lumière]] qui doit être amenée en quantité et qualité suffisantes, et si possible orientée du haut vers le bas pour assurer une bonne croissance aux végétaux. Le mur végétalisé d'intérieur peut être construit dans une [[véranda]] ou sous une verrière, en prenant garde aux éventuelles surchauffes et aux problèmes éventuels liés à l'eau et à la condensation.
Une première manière de végétaliser le mur est de mettre sur la surface un substrat apte à être colonisé par les végétaux choisis. Ce substrat sera comparable à celui des toitures végétalisées, ou de type feutre synthétique associé à un système de pompe (éventuellement solaire) maintenant un écoulement d'eau le long du substrat qui sera progressivement colonisé par les végétaux qu'on y aura plantés.
Quelques exemples de réalisations intérieures innovantes :
<gallery>
Image:Bar végétalisé 2.JPG|<div style="text-align: center;">Bar végétalisé</div>
Image:Triptik.png|<div style="text-align: center;">Le tableau végétal</div>
Image:Mur végétal intérieur.jpg|<div style="text-align: center;">Un Mur intérieur</div>
</gallery>
{{message galerie}}
Il est aussi possible de planter des végétaux grimpants, buissonnants ou arbres dans le "vrai sol" ; Ainsi dans le lycée [[w:Haute qualité environnementale|HQE]] de Calais, des arbres ont été plantés sous les verrières intérieures, non dans des fosses qui nécessiterait un arrosage, mais dans le vrai sol réservé par l'architecte.
On peut aussi faire entrer le végétal (type lierre ou plante grimpante) par un orifice réservé en bas du mur, garni d'un isolant, tout en laissant ses racines s'épanouir dans le sol à l'extérieur. Les végétaux à crampons ou racines aériennes prennent appui sur la structure et colonisent progressivement le mur. Il faut cependant mettre en place un système permettant d'empêcher l'accès aux araignées, souris et autres indésirables par l'orifice d'accès du végétal. Ce système est le plus simple, car il ne nécessite quasiment pas d'entretien, si ce n'est une taille régulière pour éviter l'envahissement de la maison. En général, il n’est pas nécessaire de l'arroser puisque le végétal a ses racines à l'extérieur, sauf en cas de sécheresse prolongée.
L'intérêt principal du mur végétalisé peut être le [[w:renouvellement de l'air intérieur|renouvellement de l'air intérieur]] ou la [[w:phytoremédiation|phytoremédiation]]. Voir aussi le programme [[w:Phyt'air|Phyt'air]].
=== Le mobilier urbain végétalisé ===
[[Image:LierrePoteau.jpg|thumb|Poteau électrique et support de [[w:lampadaire|lampadaire]] couverts de lierre. <br />Sans remplacer un arbre, ce poteau rembourse une partie de sa [[w:Dette écologique|dette écologique]] en produisant de l'oxygène toute l'année et en offrant gîte et couvert aux oiseaux et à d'autres animaux.]]
Pour pallier le manque d'arbres et de photosynthèse en milieu urbain, une grande partie du mobilier urbain pourrait être végétalisé :
* [[w:Poteau électrique|Poteau électrique]] ;
* [[w:Lampadaire|Lampadaire]] ;
* [[w:Banc public|Banc public]] ;
* [[w:Abribus|Abribus]], etc.
Plusieurs solutions sont possibles : plantations directement dans le sol lorsque c'est possible (végétalisation auto-entretenue) ou dans des bacs de volume variable en fonction de la taille de la structure (il faut alors arroser le végétal régulièrement, au moins les premières années).
Les [[toiture végétale|toitures-terrasses végétalisées]] peuvent également compléter ces dispositifs, ne nécessitant que peu d'entretien s'il s'agit d'une végétalisation extensive ([[sédum]]s..).
==Prospective ==
L'objectif de stopper la perte de biodiversité en 2010 ou avant 2012 implique de contribuer à la restaurer partout où cela se peut, dont en ville et dans ou sur le bâti;
(début d'article, non terminé. Aide bienvenue)
{{...}}
==Bibliographie==
* Noël Dunnett ''Toits et murs végétaux'' ; Éd. du Rouergue, Rodez, 2008
* Jean-Michel Groult, ''Créer un mur végétal''/ Paris : Ulmer ; DL 2008
* Kindt, Agnes (Institut du Développement Durable et Responsable), Véronique DHAM (Gondwana), présentation ''[http://www.gecina.fr/fo/fileadmin/user_upload/Developpement%20durable/GECINALAB/2012/Horizons%20-Biodiversite-%2003%2004%2012.pdf La Biodiversité, semaine du développement durable]'', 3 avril 2012. IDDR Université catholique de Lille. Conférence Gecina
* Lewandowski, Delphine (2021) Étude et définition théoriques, techniques et biologiques d’un mur « biodiversitaire » – Un nouveau système de végétalisation vertical favorisant la biodiversité, thèse Paris Est, sous la direction de Robert Le Roy et Philippe Clergeau, www.theses.fr/s235700, en partenariat avec l’agence ChartierDalix, la plateforme Faire et le Pavillon de l’Arsenal, https://cesco.mnhn.fr/fr/actualites/un-mur-biodiversitaire-sinstalle-devant-le-laboratoire-6434.
==Notes et références pour ce sous-chapitre==
<references />
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|L'enveloppe du bâti elle-même ]]
qiir54tff0lka31v2uhyasj142p5ich
764237
764234
2026-04-21T15:17:47Z
Lamiot
1916
forme, compléments
764237
wikitext
text/x-wiki
[[Image:HK Kennedy Town Forbes Street w1.jpg|thumb|upright=1.5|Dans certaines conditions, la végétation - et ici son système racinaire - peut envelopper ou couvrir un mur ancien, en l’abîmant peu, voire en le protégeant (ici à [[w:fr:Hong Kong|Hong Kong]])]]
Diverses parties de l'enveloppe ou du support (poteaux, etc) d'une construction peuvent abriter ou faciliter la vie de nombreuses espèces d'animaux et végétaux, sans que cela nuise à la structure ou aux fonctions du bâti si ce dernier est conçu pour empêcher sa dégradation par la faune, la flore et les champignons, et pour empêcher les contacts directs entre la faune et les habitants ou usagers dans le cas de structures habitées.
==L'architecture traditionnelle==
[[File:Ruche pédagogiqueKCC2008Lamiot3.jpg|thumb|left|upright=1.3|Cette ruche "pédagogique" située dans un bâtiment (magasin et lieu de réunion) de l'ONG anglais [http://kentwildlife.smartchange.org/ Kent Wildlife trust] et KMRBC ([http://www.kmbrc.org.uk/aboutus/aboutKMBRC/index.php Kent & Medway Biological Records Centre]) (Kent, Royaume-Uni) permet de voir les abeilles au travers des vitres, d'écouter leur vrombissement, de sentir l'odeur de la ruche, grâce des orifices grillagés ; placée à l'ombre, elle communique avec l'extérieur via un conduit traversant le mur]]
[[File:Bee boles.jpg|thumb|upright=1|Niches dans un mur de brique, abritant des ruches traditionnelles (pour produire miel et cire), mais aussi utile pour polliniser les fruitiers proches (Lost Gardens of Heligan, Cornouaille, Royaume-Uni)]]
[[File:Beehivepubsign.jpg|thumb|upright=1|Enseigne anglaise faite d'une véritable ruche, habitée par des abeilles (Beehive Inn, Grantham, Royaume-Uni]]
* '''Concernant la flore''' : <br />Les toitures végétalisées semblent avoir été courantes et anciennes en Europe du nord.
<br />Des plantes grimpantes (lierre, vigne vierge, chèvre feuille ont également colonisé des murs de toutes sorte depuis longtemps en zone tempérée.
<br />En zone tropicale et équatoriale, la flore (très exubérante) est la faune sauvage sont au contraire maintenue à distance.
* '''Concernant la faune''' : <br />En Europe et Asie du nord, l'habitat humain, les fermes et les châteaux semblent - depuis les débuts de l'histoire de l'architecture - avoir accordé une large place à la faune domestiquée ;
<br />ainsi trouve-ton des traces anciennes de niches et chenils pour les chiens (chiens de garde ou de chasse), poulaillers, chatières... <br>Des écuries et étables adossées à la ferme, ou formant son rez de chaussée étaient fréquent dans le moyen-âge européen.
<br/>Des pigeonniers, voire des ruchers pouvaient être intégrés dans les murs, respectivement pour la récolte de fientes (comme engrais), d’œufs, la viande de pigeon et pour le miel et la cire).
<br />Plusieurs espèces d'hirondelles qui débarrassaient les étables et écuries des nuées de mouches attirées par les animaux et leur fumier sont devenues si proches de l'homme qu'on les caractérise souvent comme [[w:Commensal|commensale]]s de l'homme.
{{clear}}
==L'architecture contemporaine==
Certains architectes, dans les projets où la qualité environnementale est privilégiée, accordent depuis peu une place croissante à la flore, et commencent parfois à intégrer la faune sauvage dans leurs projets. Le concept de « maison-nichoir » a en France été promu par Jean-François Noblet (voir bibliographie)
==Le mur végétalisé==
Dans sa [https://theses.hal.science/tel-04536164 Thèse sur les'' murs biodiverses''] (murs ou parois conçus pour accueillir la biodiversité tout en contribuant à la régulation thermique des bâtiments), soutenue à l'Université Paris-Est, en 2023, Delphine Lewandowski présente la manière dont un réseau interne continu de substrat organique peut permettre l’installation durable du vivant, à certaines conditions. Elle a étudié :
:- le rôle et la gestion de l’eau dans un tel système vertical ;
:- l’installation et le maintien des plantes et du substrat ;
:- la biocompatibilité et ''bioréceptivité des matériaux'' (capacité à accueillir des organismes vivants) ;
:- la morphologie des murs (quantité, nature et qualité des interstices, des irrégularités, des volumes...).
Pour répondre à ces enjeux, D.Lewandowski a adopté une approche multidisciplinaire mêlant architecture, science des matériaux, écologie urbaine et science des sols, dans 3 expérimentations principales :
# Étude à l’échelle 1:1 de trois murs biodiversitaires maçonnés : <br>- Deux murs en briques d’argile cuite et un en pierre sèche ; <br>- Observation sur plusieurs saisons ; <br>- Facteurs influençant la biodiversité : orientation, hauteur, humidité, pH, densité, capacité thermique, albédo, morphologie ;<br>- Résultat : formulation de recommandations de conception.
# Analyse de la bioréceptivité des matériaux, évaluée par des expérimentations en serre avec deux plantes muricoles ; des tests sur trois bétons et une brique concassés, avec ou sans compost, avec comme résultat majeur que le pH du matériau et du substrat de croissance influencent fortement la croissance végétale
# Étude du comportement du substrat en verticalité, avec une analyse du tassement et de la teneur en eau du substrat selon sa granulométrie, qui montre la nécessité d’un substrat contenant une proportion élevée de gros grains rigides pour limiter le tassement et assurer une bonne répartition de l’eau.
== Histoire, réhabilitation historiques... ==
[[File:MoutonSoaySoaySheepUrbanGrazing2012LilleLamiotF 03.JPG|thumb|250px|[[w:fr:Mouton de Soay|Moutons de Soay]] utilisés pour la [[w:fr:Gestion restauratoire|gestion restauratoire]] de la végétation couvrant le sommet des murs d'une partie récemment restaurée des fortifications de la [[w:fr:Citadelle de Lille|Citadelle de Lille]]. Très à l'aise sur les pentes, cet animal remplace la tondeuse tout en jouant un rôle de ''[[w:fr:Corridor biologique|corridor écologique]] ambulant'' (il véhicule des [[w:fr:Graine|graine]]s et [[w:fr:Propagule|propagule]]s dans son pelage, son tube digestif et sous ses sabots)]]
[[File:Écomatériaux biodiversité construction Lille 2016 a Citadelle 8.JPG|thumb|left|upright=1.4|Sur une partie des fortifications (contre-garde), une expérimentation en faveur de la biodiversité doit permettre à quelques espèces végétales et animales « muricoles » (invertébrés, chauve-souris) de continuer à vivre sur le site, et faciliter leur observation par le public.<br /> Sur quelques dizaines de mètre des parpaings spéciaux ont été maçonnés avec de la terre, et remplis d'une terre compact (riche en argile et chaux). Les spores et graines sauvages adaptées au milieu sont apportées par le vent, les insectes, les oiseaux, etc. les espèces s'auto-sélectionnent et s'adaptent à ce microclimat particulier (chaud et sec en été, très exposé au vent).]]
[[File:Gabion terre pierre Citadelle Lille biodiversité 2016 Lamiot a.JPG|thumb|left|upright=1.4|Sur quelques mètres, et dans le même objectif que sur l'image ci-dessus, une autre expérience utiliser des [[w:gabion|gabions]] emplis de petites pierres calcaire dure et de terre.]]
La colonisation naturelle de murs et murets par des plantes (dont arbres) est naturelle.
Elle est habituellement considérée comme un problème, les racines endommageant les mortiers naturels de terre ou de chaux hydraulique naturelle, surtout s'ils sont souvent humides. Ces racines peuvent dans certaines conditions, décoller les briques ou encore favoriser l'humidité du mur (ou au contraire la drainer), ou augmenter sa vulnérabilité au gel (ex : cas des murs de fortification dont le cœur est constituée de pierre calcaire gélive, cachées sous un parement protecteur de pierre dure ou de brique). <br />En zone tropicale humide, certains arbres peuvent rapidement coloniser et entièrement recouvrir des architectures (dont patrimoniales telles que celles des temples d'[[w:fr:Angkor|Angkor]] en quelques siècles).
Des structures architectoniques artificielles, ciment ou appareils de pierres maçonnées, que l'on laisse volontairement se couvrir de [[w:Bryophyte|mousse]]s et de quelques plantes [[w:muricole|muricoles]] ([[w:Fougère|fougère]]s notamment) existent néanmoins (depuis plus de 200 ans au moins en France dans quelques grands parcs royaux ou municipaux, initialement toujours associés à des fontaines ou cascades).
Les "fabriques" romantiques (faux bâtiments anciens, fausses ruines) les ont beaucoup apprécié au XIXe siècle.
Ils ont ensuite été développés par certains [[w:zoo|zoos]] et pour le décor de [[w:fr:terrarium|terrarium]]s ou d'[[w:fr:aquaterrarium|aquaterrarium]]s publics ou privés, utilisant généralement des espèces tropicales en culture [[w:hydroponique|hydroponique]]<ref>http://jardin-botanique.ups-tlse.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1221657599742&ID_FICHE=68457 Fiche du Jardin botanique Henri Gaussen, présentant un mur végétal tropical élaboré par Patrick Blanc], pdf, 1 page </ref>, avant que le [[w:fr:Botaniste|botaniste]] et chercheur français [[w:fr:Patrick Blanc|Patrick Blanc]] ne crée, teste et développe son concept [[w:fr:horticulture|horticole]] de ''mur végétal'' sur support de feutre horticole.
D'autres techniques de murs végétaux se développent et dans leur sillage ou indépendamment, des designers et paysagistes ont développé de nouvelles méthodes et outils pour les espaces intérieurs. Des systèmes en kits prévégétalisés à assembler existent <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/technologie-de-realisation-du-mur-vegetal-et-du-jardin-vertical-greenwall.html Système de kits, de Greenwall Végétalis, conçu avec l'aide de scientifiques]</ref> ou de supports conçus avec l'aide de scientifique et d'un logiciel de modélisation de la croissance des plantes (croissance, aspect, couleur...) <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/mur-vegetal-et-jardin-vertical-vivant.html Voir la Animation 4D réalisée par l’ U.M.R A.M.A.P du CIRAD sur une suite logicielle (Orchestra®) de Bionatics.] (consulté 2010/30/08)</ref>, Fedor van der Valk a inventé de minis-jardins suspendus intérieurs (« ''String Gardens'' ») qui semblent flotter dans le vide en supportant des cascades de verdure. Le néo-zélandais Patrick Morris réussit à donner l'impression que le plafond est tapissé de plantes, via des jardinières à double fond qui y sont suspendues. L'équipe d'Amaury Gallon vient installer un mur végétal en kit, installé à domicile. Le designer Richard Grassin Delyle propose des cloisons ou doubles cloisons végétalisées, éventuellement mobiles, avec plantes fixées sur tissus horticole horizontal <ref>[http://www.mur-vegetal-interieur.fr/mur-vegetal.html Présentation des cloisons végétales de Richard Grassin Delyle] (avec réserve d'eau pour 3 à 4 semaines, mais nécessitant une prise électrique)</ref>. De nombreux exemples de murs intérieurs sont aujourd'hui disponibles<ref>[http://aquakarma974.over-blog.com/ Ex : Jardin vertical intérieur de 33 m3 d'Aquakarma 974]</ref>.
Le [[w:Gabion|gabionnage]] a encore donné lieu au XXème siècle à divers [[w:innovation|innovation]]s<ref>ex : CLAUZEL, L. (1963). ''[http://documents.irevues.inist.fr/bitstream/handle/2042/24557/RFF_1963_6_512.pdf?sequence=1? Un nouveau système de gabions: les coffres en treillis d'acier remplis en hérisson]''.</ref> et [[w:brevet (invention)|brevets]]<ref>ex : Hilfiker, W. K. (1991). U.S. Patent No. 5,076,735. Washington, DC: U.S. Patent and Trademark Office (brevet)</ref>, mais leur relative simplicité de fabrication peut permettre comme au [[w:fr:Burkina Faso|Burkina Faso]] de les faire fabriquer par des artisans locaux<ref>Royet, P. (1992). Les ouvrages en gabions, [http://agris.fao.org/agris-search/search.do?recordID=FR19960033446 fiche Agris-FAO]</ref>. On a notamment essayé d'y intégrer des fonctions de [[w:fr:Service écosystémique|services écosystémiques]] en les rendant parfois plus propices à la [[w:fr:Biodiversité|biodiversité]], par exemple en permettant leur colonisation par des [[w:racine|racine]]s d'[[w:racine|arbre]]s<ref>Koch, D. (1994). ''Essai d'intégration de la végétation dans les gabions sur un chantier de construction de route au Népal central'' (Doctoral dissertation).</ref>
{{clear}}
== Principe ==
[[File:04_-_Végétalis®_chevalets.jpg|thumb|upright=1|left|Des producteurs (ici ''murs végétalis®'') proposent des mélanges d'espèces et de variétés permettant une meilleure résistance aux maladies…]]
[[File:Greenbox®.jpg|thumb|250px|Module ''Greenbox®'']]
[[File:Végétalis® école archi.jpg|thumb|upright=1|Mur végétalis® de l'[[w:école d'architecture de Montpellier|école d'architecture de Montpellier]], don de la société ''Greenwall'']]
[[File:03_-_Cultures_végétalis.jpg|thumb|upright=1|Les plantes préparées sur une surface presque verticale auront un aspect plus naturel dès leur installation sur le mur (Cultures végétalis®)]]
Des murs ou parois végétalisées peuvent être aménagés tant à l'extérieur qu'à l'intérieur de bâtiments, avec ou sans source artificielle de lumière.
<br>Le principe s'appuie sur le fait qu'en l'absence d'intervention humaine, en présence d'air propre et d'une humidité suffisante de l'air, tout support tend à être naturellement colonisé par des bactéries ([[w:fr:Biofilm|biofilm]]), des [[w:fr:Algues|algue]]s, puis des [[w:mousse (botanique)|mousse]]s et des [[w:Lichen|lichen]]s, avant l'apparition de petites plantes, qui sont généralement aussi des épiphytes des arbres. Dans le cas où le mur reste sec, ou en atmosphère plus sèche, il peut également être colonisé par des plantes grimpantes ([[w:Lierre grimpant|lierre]], [[w:Vigne vierge|vigne vierge]] en [[w:Climat tempéré|climat tempéré]]).
<br>Plusieurs approches techniques existent, allant de l'insertion de plantes adaptées aux milieux secs et pauvres (crassulantes, cactées..) pour créer des structure de type ''« jardins de rocailles »'', à des techniques sophistiquées dites de "génie végétal" optimisant les conditions de colonisation et de pousse des plantes grâce à des supports de feutre synthétique dans lequel circule de l'eau enrichie en sels nutritifs.
Un grand nombre de plantes tropicales épiphytes ou poussant à l'ombre de la canopée se contentent de peu de lumière et de peu de nutriments.
== Types d'aménagement de façades ==
Il peut se faire soit à partir du sol directement, les racines de plantes grimpantes y puisant leur nourriture et l'eau, soit en intégrant la flore au bâtiment, via des balconnières, des jardinières, ou des systèmes plus complexe de murs végétaux tels que ceux de [[w:patrick Blanc|Patrick Blanc]].
'''Par exemple :''' Sur le mur porteur est placé une ossature métallique qui soutient une plaque de [[w:Chlorure de polyvinyle|PVC]] expansé de 10 mm d'épaisseur, sur laquelle sont agrafées deux couches de feutre de [[polyamide]] de 3 mm d'épaisseur chacune. Ces couches de feutre miment en quelque sorte les [[w:mousse (botanique)|mousse]]s qui se développent sur les parois rocheuses et qui servent de support aux [[w:Racine (botanique)|racines]] des plantes. Un réseau de tuyaux commandés par des électrovannes apporte une [[w:engrais|solution nutritive]] contenant les éléments minéraux nécessaires à la croissance des plantes. Le feutre s'imprègne de cette solution nutritive, qui redescend le long du mur par gravité. Les racines des plantes n'ont qu'à se servir, et l'eau en excès est recueillie en bas du mur par une gouttière, avant d'être réinjectée dans le réseau de tuyaux : le système fonctionne en circuit fermé.
C'est une variation inhabituelle d'une [[w:machine vivante|machine vivante]] : l'eau s'écoule sur une surface sur laquelle se développent de la [[w:mousse (botanique)|mousse]] ou d'autres plantes, quelques [[w:Arthropode|arthropodes]]s et des [[w:Bactérie|bactérie]]s, et est captée en bas du mur dans une [[w:Gouttière (architecture)|gouttière]], d'où elle est réinjectée en haut du mur.
== Les avantages ==
En plus de l'aspect esthétique, le mur végétalisé présente plusieurs avantages :
*Il permet une meilleure régulation thermique du bâtiment. En été, l'ensoleillement est réduit.
*L'[[w:évapotranspirationévapotranspiration]] du lierre ou d'autres grimpantes contribue au rafraîchissement de l'air et à une régulation de l'[[w:Hygrométrie|hygrométrie]]. En hiver, ce couvert végétal seul ne peut jouer un véritable rôle d'[[w:Isolation (construction)|isolant]], mais en asséchant les fondations et en protégeant les murs de la pluie (grâce à l'orientation des feuilles et à leur densité dans le cas du lierre), il les rend plus [[w:Isolant|isolant]]s.
*Il protège le bâtiment contre l'effet corrosif des pollutions urbaines ([[w:Pluie acide|pluie acide]], [[w:Pollution de l'air|pollution atmosphérique]]) et contre l’humidité (acide, en ville), en offrant une surface imperméable à la pluie. En effet, la disposition "en tuiles" des feuilles de certaines grimpantes, telles que le lierre, permet de protéger presque totalement le mur de la pluie.
*Les racines participent à l'assèchement du sol à proximité des fondations.
*La végétalisation des façades offre une surface végétale supplémentaire et significative pour l'épuration de l'air et la production d'oxygène.
*Certains [[w:mur anti-bruit|murs anti-bruit]] sont végétalisés, augmentant leur fonction dé-stressante (végétalis®, Le Prieuré, Héliotrope…). Le feuillage seul est réputé inefficace (une épaisseur de 10 m de feuillage d'arbres ne réduit un son puissant que d'à peine 1 dba), cependant le bruit du vent dans les feuilles et celui des oiseaux (comme celui des fontaines) ont des vertus psychologiquement apaisantes, et sans vraiment cacher le bruit ambiant, ils le rendent plus supportable.
== Utilisation du lierre ==
Le [[w:fr:Lierre grimpant|lierre]] est une plante particulièrement bien adaptée au verdissement des façades. Sauf dans le cas de murs maçonnés à la [[w:fr:Chaux (chimie)|Chaux hydraulique naturelle]] ou à la terre et qui seraient assez humides pour que les racines puissent y vivre, ce végétal n'abîme pas les façades, bien qu'il puisse endommager les peintures où ses crampons laissent des traces. Il est résistant aux conditions climatiques rudes ([[w:fr:inondation|inondation]], gel, [[w:fr:sécheresse|sécheresse]]...). Il reste vert toute l'année, ce qui lui permet de continuer à absorber du carbone pendant l'hiver, alors que la plupart des végétaux ont perdu leurs feuilles. La période de pollinisation du lierre se situe vers la fin de l'été. Il offre donc aux invertébrés pollinisateurs la possibilité de bénéficier d'un dernier approvisionnement en [[w:fr:Pollen|pollen]] avant l'hiver. Les fruits du lierre apparaissent très tôt dans l'année (vers le mois de mars), et constituent une nourriture de base pour les oiseaux frugivores, alors que leur nourriture fraîche commence à manquer. De plus, au même titre que certaines autres espèces indigènes ([[w:fr:Fougère|fougère]]s, [[w:fr:Cymbalaire|cymbalaire]]), le lierre possède une valeur esthétique.
Les autres espèces couramment utilisées sont la [[w:fr:Vigne vierge|vigne vierge]], le [[w:fr:Chèvrefeuille|chèvrefeuille]]...
== Entretien ==
Afin de préserver au maximum le potentiel de végétalisation des façades, le mur doit conserver ses irrégularités, sans altérer l'état général de la surface. Faire grimper du lierre sur un mur dont les joints sont abîmés (joints sableux) peut être dommageable pour la surface.
L'entretien des façades ne peut pas se faire à toutes les époques de l'année afin de respecter les rythmes de la faune et de la flore qui y auront trouvé refuge. Il faut éviter les périodes de [[w:nidification|nidification]] ou les périodes de froid hivernal pendant lesquelles la végétation sert d'abri pour de nombreux [[w:invertébré|invertébré]]s.
Afin de faciliter la [[w:végétalisation|végétalisation]] suivant un processus naturel, il faut conserver des îlots de végétation (mousse, fougères) lors de l'entretien des façades.
Une attention particulière doit être apportée à l’entretien des façades et structures végétalisées. Si les plantes grimpantes ou la flore des [[w:Toiture végétale|terrasses extensives]] sont rustiques et ne nécessitent ni arrosage ni engrais. Il faut respecter les points suivants :
*Les [[w:plante grimpante|plantes grimpantes]] ne doivent pas atteindre les tuiles, ardoises ni les [[w:Gouttière (architecture)|gouttière]]s. Si leurs feuilles mortes bouchaient ou freinaient l’évacuation des eaux pluviales, celles-ci pourraient déborder et s’écouler le long des façades, au risque d’altérer les matériaux, de favoriser la pénétration de racines et l'implantation de fougères, graminées, voire de plantes buissonnantes ou d'arbres dans les ciments de mauvaise qualité ou composés de chaux hydraulique naturelle, ou de terre.
**De la même façon, il faut tailler régulièrement les végétaux autour des ouvertures, prises d'air, cheminées, de manière que la végétation ne guide pas des espèces indésirables ou invasives vers les espaces intérieurs (insectes (comme les fourmis) ou araignées...). Un filtre de type moustiquaire peut protéger les prises d'air.
*Le pourtour des terrasses végétalisées doit être nettoyé ou inspecté une à 2 fois par an de manière à vérifier que les drains ne soient pas bouchés (par feuilles mortes, cadavres d'oiseaux, etc, ce qui vaut aussi pour les terrasses non végétalisées).
*Quelques plantes grimpantes, telles que la [[w:glycine (plante)|glycine]], peuvent s’enrouler autour des gouttières, des tuyauteries, et les compresser jusqu’à la rupture. Il faut donc contrôler, guider sélectionner ou adapter la végétalisation en fonction du type de mur ou de support.
Pour favoriser une [[w:Biodiversité|biodiversité]] aussi proche que possible du potentiel local, toutes les surfaces du bâti, autres que les vitres et les panneaux solaires peuvent être végétalisées.
== Précautions, sécurité ==
[[Image:GlycineGouttière.jpg|thumb|right|300px|Une [[w:Glycine|glycine]] enroulée autour d'une gouttière peut finir par la tordre ou l'écraser. Mieux vaut guider ce type de grimpante sur un support préparé pour elle.]]
L'aménageur doit prendre en compte les problèmes qui peuvent être posés par l'humidité (salissures par les spores de fougères, de mousses et de champignons, risques de court-circuit en cas d'éclairage artificiel, de chauffage, présence de pompes, etc.), et par le poids des végétaux qui grandissent.
Ces murs peuvent aussi être colonisés par une faune d'invertébrés tolérés ou souhaités en aquaterrarium, mais non désirés dans une habitation ou un lieu public.
Dans le cas de murs végétaux, le mur ou le support, s'ils ne sont pas conçus par l'architecte pour résister à l'eau enrichie de nutriments, doivent en être protégés.
Certains murs maçonnés à la terre ou à la chaux hydraulique doivent être protégés de la pénétration de racines susceptibles de les dégrader.
Un entretien et des vérifications régulières sont nécessaires.
En cas d'utilisation de plantes exotiques, afin d'éviter d'importer des organismes indésirables ou microbes pathogènes, il est recommandé de travailler avec des horticulteurs spécialisés et des plantes dont l'origine est traçable et légale.
== Les oiseaux ==
Le fait d'augmenter la biodiversité augmente aussi la présence des oiseaux. Or, les surfaces vitrées constituent un piège visuel pour l'avifaune qui percute des fenêtres de jour ou de nuit.
*L'oiseau peut être victime d'un effet miroir lorsque la vitre reflète le ciel.
*Il peut penser pouvoir traverser le bâtiment lorsqu'il aperçoit une autre ouverture dans le même axe.
*Il peut percuter une vitre invisible de type mur antibruit ou de type « balustrade vitrée » par exemple sur une terrasse.
*De nuit, des oiseaux en migration percutent fréquemment des fenêtres d'une pièce éclairée (c'est l'un des aspects de la [[w:pollution lumineuse|pollution lumineuse]].
La fréquence des collisions nocturnes avec des vitres éclairées peut être diminuée de 80 % par la fermeture d'un volet ou d'un rideau épais.
<br>Et de jour, on diminue fortement le risque de collision par l'apposition d'une silhouette noire représentant un oiseau de proie, encore plus efficacement si celle-ci est suspendue à un fil qui lui permet de bouger. Ces silhouettes sont commercialisées par différentes associations ou institutions. Elles ne gênent pas la faune locale qui s'y habitue et préviennent les collisions avec les oiseaux migrateurs ou de passage.
== Variantes intérieures ==
Une variante à la façade végétalisée est le mur intérieur végétalisé.
La seule contrainte supplémentaire concerne la [[w:éclairage nocturne|lumière]] qui doit être amenée en quantité et qualité suffisantes, et si possible orientée du haut vers le bas pour assurer une bonne croissance aux végétaux. Le mur végétalisé d'intérieur peut être construit dans une [[w:véranda|véranda]] ou sous une verrière, en prenant garde aux éventuelles surchauffes et aux problèmes éventuels liés à l'eau et à la condensation.
Une première manière de végétaliser le mur est de mettre sur la surface un substrat apte à être colonisé par les végétaux choisis. Ce substrat sera comparable à celui des toitures végétalisées, ou de type feutre synthétique associé à un système de pompe (éventuellement solaire) maintenant un écoulement d'eau le long du substrat qui sera progressivement colonisé par les végétaux qu'on y aura plantés.
Quelques exemples de réalisations intérieures innovantes :
<gallery>
Image:Bar végétalisé 2.JPG|<div style="text-align: center;">Bar végétalisé</div>
Image:Triptik.png|<div style="text-align: center;">Le tableau végétal</div>
Image:Mur végétal intérieur.jpg|<div style="text-align: center;">Un Mur intérieur</div>
</gallery>
{{message galerie}}
Il est aussi possible de planter des végétaux grimpants, buissonnants ou arbres dans le "vrai sol" ; Ainsi dans le lycée [[w:Haute qualité environnementale|HQE]] de Calais, des arbres ont été plantés sous les verrières intérieures, non dans des fosses qui nécessiterait un arrosage, mais dans le vrai sol réservé par l'architecte.
On peut aussi faire entrer le végétal (type lierre ou plante grimpante) par un orifice réservé en bas du mur, garni d'un isolant, tout en laissant ses racines s'épanouir dans le sol à l'extérieur. Les végétaux à crampons ou racines aériennes prennent appui sur la structure et colonisent progressivement le mur. Il faut cependant mettre en place un système permettant d'empêcher l'accès aux araignées, souris et autres indésirables par l'orifice d'accès du végétal. Ce système est le plus simple, car il ne nécessite quasiment pas d'entretien, si ce n'est une taille régulière pour éviter l'envahissement de la maison. En général, il n’est pas nécessaire de l'arroser puisque le végétal a ses racines à l'extérieur, sauf en cas de sécheresse prolongée.
L'intérêt principal du mur végétalisé peut être le [[w:renouvellement de l'air intérieur|renouvellement de l'air intérieur]] ou la [[w:phytoremédiation|phytoremédiation]]. Voir aussi le programme [[w:Phyt'air|Phyt'air]].
=== Le mobilier urbain végétalisé ===
[[Image:LierrePoteau.jpg|thumb|Poteau électrique et support de [[w:lampadaire|lampadaire]] couverts de lierre. <br />Sans remplacer un arbre, ce poteau ''« rembourse une partie de sa [[w:Dette écologique|dette écologique]] »'' en produisant de l'oxygène toute l'année, en produisant un pollen tardif (dernière nourriture des abeilles dans l'année) et en offrant « gîte et couvert » aux oiseaux et à d'autres animaux.]]
Pour pallier le manque d'arbres et de photosynthèse en milieu urbain, une grande partie du mobilier urbain pourrait être végétalisé :
* [[w:Poteau électrique|Poteau électrique]] ;
* [[w:Lampadaire|Lampadaire]] ;
* [[w:Banc public|Banc public]] ;
* [[w:Abribus|Abribus]], etc.
Plusieurs solutions sont possibles : plantations directement dans le sol lorsque c'est possible (végétalisation auto-entretenue) ou dans des bacs de volume variable en fonction de la taille de la structure (il faut alors arroser le végétal régulièrement, au moins les premières années).
Les [[w:toiture végétale|toitures-terrasses végétalisées]] peuvent également compléter ces dispositifs, ne nécessitant que peu d'entretien s'il s'agit d'une végétalisation extensive ([[w:sédum|sédum]]s..).
==Prospective ==
L'objectif de stopper la perte de biodiversité (objectif qui n'a pas été tenu dans les années 2010) implique de contribuer à la restaurer partout où cela se peut, dont en ville et dans ou sur le bâti;
(début d'article, non terminé. Aide bienvenue)
{{...}}
== Bibliographie ==
* Noël Dunnett ''Toits et murs végétaux'' ; Éd. du Rouergue, Rodez, 2008
* Jean-Michel Groult, ''Créer un mur végétal''/ Paris : Ulmer ; DL 2008
* Kindt, Agnes (Institut du Développement Durable et Responsable), Véronique DHAM (Gondwana), présentation ''[http://www.gecina.fr/fo/fileadmin/user_upload/Developpement%20durable/GECINALAB/2012/Horizons%20-Biodiversite-%2003%2004%2012.pdf La Biodiversité, semaine du développement durable]'', 3 avril 2012. IDDR Université catholique de Lille. Conférence Gecina
* Lewandowski, Delphine (2021) Étude et définition théoriques, techniques et biologiques d’un mur « biodiversitaire » – Un nouveau système de végétalisation vertical favorisant la biodiversité, thèse Paris Est, sous la direction de Robert Le Roy et Philippe Clergeau, www.theses.fr/s235700, en partenariat avec l’agence ChartierDalix, la plateforme Faire et le Pavillon de l’Arsenal, https://cesco.mnhn.fr/fr/actualites/un-mur-biodiversitaire-sinstalle-devant-le-laboratoire-6434.
== Notes et références pour ce sous-chapitre ==
<references />
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|L'enveloppe du bâti elle-même ]]
hb0k84250s2sq5hknewuueyse8vk8iz
764241
764237
2026-04-21T15:23:30Z
Lamiot
1916
/* Utilisation du lierre */ forme
764241
wikitext
text/x-wiki
[[Image:HK Kennedy Town Forbes Street w1.jpg|thumb|upright=1.5|Dans certaines conditions, la végétation - et ici son système racinaire - peut envelopper ou couvrir un mur ancien, en l’abîmant peu, voire en le protégeant (ici à [[w:fr:Hong Kong|Hong Kong]])]]
Diverses parties de l'enveloppe ou du support (poteaux, etc) d'une construction peuvent abriter ou faciliter la vie de nombreuses espèces d'animaux et végétaux, sans que cela nuise à la structure ou aux fonctions du bâti si ce dernier est conçu pour empêcher sa dégradation par la faune, la flore et les champignons, et pour empêcher les contacts directs entre la faune et les habitants ou usagers dans le cas de structures habitées.
==L'architecture traditionnelle==
[[File:Ruche pédagogiqueKCC2008Lamiot3.jpg|thumb|left|upright=1.3|Cette ruche "pédagogique" située dans un bâtiment (magasin et lieu de réunion) de l'ONG anglais [http://kentwildlife.smartchange.org/ Kent Wildlife trust] et KMRBC ([http://www.kmbrc.org.uk/aboutus/aboutKMBRC/index.php Kent & Medway Biological Records Centre]) (Kent, Royaume-Uni) permet de voir les abeilles au travers des vitres, d'écouter leur vrombissement, de sentir l'odeur de la ruche, grâce des orifices grillagés ; placée à l'ombre, elle communique avec l'extérieur via un conduit traversant le mur]]
[[File:Bee boles.jpg|thumb|upright=1|Niches dans un mur de brique, abritant des ruches traditionnelles (pour produire miel et cire), mais aussi utile pour polliniser les fruitiers proches (Lost Gardens of Heligan, Cornouaille, Royaume-Uni)]]
[[File:Beehivepubsign.jpg|thumb|upright=1|Enseigne anglaise faite d'une véritable ruche, habitée par des abeilles (Beehive Inn, Grantham, Royaume-Uni]]
* '''Concernant la flore''' : <br />Les toitures végétalisées semblent avoir été courantes et anciennes en Europe du nord.
<br />Des plantes grimpantes (lierre, vigne vierge, chèvre feuille ont également colonisé des murs de toutes sorte depuis longtemps en zone tempérée.
<br />En zone tropicale et équatoriale, la flore (très exubérante) est la faune sauvage sont au contraire maintenue à distance.
* '''Concernant la faune''' : <br />En Europe et Asie du nord, l'habitat humain, les fermes et les châteaux semblent - depuis les débuts de l'histoire de l'architecture - avoir accordé une large place à la faune domestiquée ;
<br />ainsi trouve-ton des traces anciennes de niches et chenils pour les chiens (chiens de garde ou de chasse), poulaillers, chatières... <br>Des écuries et étables adossées à la ferme, ou formant son rez de chaussée étaient fréquent dans le moyen-âge européen.
<br/>Des pigeonniers, voire des ruchers pouvaient être intégrés dans les murs, respectivement pour la récolte de fientes (comme engrais), d’œufs, la viande de pigeon et pour le miel et la cire).
<br />Plusieurs espèces d'hirondelles qui débarrassaient les étables et écuries des nuées de mouches attirées par les animaux et leur fumier sont devenues si proches de l'homme qu'on les caractérise souvent comme [[w:Commensal|commensale]]s de l'homme.
{{clear}}
==L'architecture contemporaine==
Certains architectes, dans les projets où la qualité environnementale est privilégiée, accordent depuis peu une place croissante à la flore, et commencent parfois à intégrer la faune sauvage dans leurs projets. Le concept de « maison-nichoir » a en France été promu par Jean-François Noblet (voir bibliographie)
==Le mur végétalisé==
Dans sa [https://theses.hal.science/tel-04536164 Thèse sur les'' murs biodiverses''] (murs ou parois conçus pour accueillir la biodiversité tout en contribuant à la régulation thermique des bâtiments), soutenue à l'Université Paris-Est, en 2023, Delphine Lewandowski présente la manière dont un réseau interne continu de substrat organique peut permettre l’installation durable du vivant, à certaines conditions. Elle a étudié :
:- le rôle et la gestion de l’eau dans un tel système vertical ;
:- l’installation et le maintien des plantes et du substrat ;
:- la biocompatibilité et ''bioréceptivité des matériaux'' (capacité à accueillir des organismes vivants) ;
:- la morphologie des murs (quantité, nature et qualité des interstices, des irrégularités, des volumes...).
Pour répondre à ces enjeux, D.Lewandowski a adopté une approche multidisciplinaire mêlant architecture, science des matériaux, écologie urbaine et science des sols, dans 3 expérimentations principales :
# Étude à l’échelle 1:1 de trois murs biodiversitaires maçonnés : <br>- Deux murs en briques d’argile cuite et un en pierre sèche ; <br>- Observation sur plusieurs saisons ; <br>- Facteurs influençant la biodiversité : orientation, hauteur, humidité, pH, densité, capacité thermique, albédo, morphologie ;<br>- Résultat : formulation de recommandations de conception.
# Analyse de la bioréceptivité des matériaux, évaluée par des expérimentations en serre avec deux plantes muricoles ; des tests sur trois bétons et une brique concassés, avec ou sans compost, avec comme résultat majeur que le pH du matériau et du substrat de croissance influencent fortement la croissance végétale
# Étude du comportement du substrat en verticalité, avec une analyse du tassement et de la teneur en eau du substrat selon sa granulométrie, qui montre la nécessité d’un substrat contenant une proportion élevée de gros grains rigides pour limiter le tassement et assurer une bonne répartition de l’eau.
== Histoire, réhabilitation historiques... ==
[[File:MoutonSoaySoaySheepUrbanGrazing2012LilleLamiotF 03.JPG|thumb|250px|[[w:fr:Mouton de Soay|Moutons de Soay]] utilisés pour la [[w:fr:Gestion restauratoire|gestion restauratoire]] de la végétation couvrant le sommet des murs d'une partie récemment restaurée des fortifications de la [[w:fr:Citadelle de Lille|Citadelle de Lille]]. Très à l'aise sur les pentes, cet animal remplace la tondeuse tout en jouant un rôle de ''[[w:fr:Corridor biologique|corridor écologique]] ambulant'' (il véhicule des [[w:fr:Graine|graine]]s et [[w:fr:Propagule|propagule]]s dans son pelage, son tube digestif et sous ses sabots)]]
[[File:Écomatériaux biodiversité construction Lille 2016 a Citadelle 8.JPG|thumb|left|upright=1.4|Sur une partie des fortifications (contre-garde), une expérimentation en faveur de la biodiversité doit permettre à quelques espèces végétales et animales « muricoles » (invertébrés, chauve-souris) de continuer à vivre sur le site, et faciliter leur observation par le public.<br /> Sur quelques dizaines de mètre des parpaings spéciaux ont été maçonnés avec de la terre, et remplis d'une terre compact (riche en argile et chaux). Les spores et graines sauvages adaptées au milieu sont apportées par le vent, les insectes, les oiseaux, etc. les espèces s'auto-sélectionnent et s'adaptent à ce microclimat particulier (chaud et sec en été, très exposé au vent).]]
[[File:Gabion terre pierre Citadelle Lille biodiversité 2016 Lamiot a.JPG|thumb|left|upright=1.4|Sur quelques mètres, et dans le même objectif que sur l'image ci-dessus, une autre expérience utiliser des [[w:gabion|gabions]] emplis de petites pierres calcaire dure et de terre.]]
La colonisation naturelle de murs et murets par des plantes (dont arbres) est naturelle.
Elle est habituellement considérée comme un problème, les racines endommageant les mortiers naturels de terre ou de chaux hydraulique naturelle, surtout s'ils sont souvent humides. Ces racines peuvent dans certaines conditions, décoller les briques ou encore favoriser l'humidité du mur (ou au contraire la drainer), ou augmenter sa vulnérabilité au gel (ex : cas des murs de fortification dont le cœur est constituée de pierre calcaire gélive, cachées sous un parement protecteur de pierre dure ou de brique). <br />En zone tropicale humide, certains arbres peuvent rapidement coloniser et entièrement recouvrir des architectures (dont patrimoniales telles que celles des temples d'[[w:fr:Angkor|Angkor]] en quelques siècles).
Des structures architectoniques artificielles, ciment ou appareils de pierres maçonnées, que l'on laisse volontairement se couvrir de [[w:Bryophyte|mousse]]s et de quelques plantes [[w:muricole|muricoles]] ([[w:Fougère|fougère]]s notamment) existent néanmoins (depuis plus de 200 ans au moins en France dans quelques grands parcs royaux ou municipaux, initialement toujours associés à des fontaines ou cascades).
Les "fabriques" romantiques (faux bâtiments anciens, fausses ruines) les ont beaucoup apprécié au XIXe siècle.
Ils ont ensuite été développés par certains [[w:zoo|zoos]] et pour le décor de [[w:fr:terrarium|terrarium]]s ou d'[[w:fr:aquaterrarium|aquaterrarium]]s publics ou privés, utilisant généralement des espèces tropicales en culture [[w:hydroponique|hydroponique]]<ref>http://jardin-botanique.ups-tlse.fr/servlet/com.univ.collaboratif.utils.LectureFichiergw?CODE_FICHIER=1221657599742&ID_FICHE=68457 Fiche du Jardin botanique Henri Gaussen, présentant un mur végétal tropical élaboré par Patrick Blanc], pdf, 1 page </ref>, avant que le [[w:fr:Botaniste|botaniste]] et chercheur français [[w:fr:Patrick Blanc|Patrick Blanc]] ne crée, teste et développe son concept [[w:fr:horticulture|horticole]] de ''mur végétal'' sur support de feutre horticole.
D'autres techniques de murs végétaux se développent et dans leur sillage ou indépendamment, des designers et paysagistes ont développé de nouvelles méthodes et outils pour les espaces intérieurs. Des systèmes en kits prévégétalisés à assembler existent <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/technologie-de-realisation-du-mur-vegetal-et-du-jardin-vertical-greenwall.html Système de kits, de Greenwall Végétalis, conçu avec l'aide de scientifiques]</ref> ou de supports conçus avec l'aide de scientifique et d'un logiciel de modélisation de la croissance des plantes (croissance, aspect, couleur...) <ref>[http://www.greenwall.fr/le-mur-vegetal-greenwall/mur-vegetal-et-jardin-vertical-vivant.html Voir la Animation 4D réalisée par l’ U.M.R A.M.A.P du CIRAD sur une suite logicielle (Orchestra®) de Bionatics.] (consulté 2010/30/08)</ref>, Fedor van der Valk a inventé de minis-jardins suspendus intérieurs (« ''String Gardens'' ») qui semblent flotter dans le vide en supportant des cascades de verdure. Le néo-zélandais Patrick Morris réussit à donner l'impression que le plafond est tapissé de plantes, via des jardinières à double fond qui y sont suspendues. L'équipe d'Amaury Gallon vient installer un mur végétal en kit, installé à domicile. Le designer Richard Grassin Delyle propose des cloisons ou doubles cloisons végétalisées, éventuellement mobiles, avec plantes fixées sur tissus horticole horizontal <ref>[http://www.mur-vegetal-interieur.fr/mur-vegetal.html Présentation des cloisons végétales de Richard Grassin Delyle] (avec réserve d'eau pour 3 à 4 semaines, mais nécessitant une prise électrique)</ref>. De nombreux exemples de murs intérieurs sont aujourd'hui disponibles<ref>[http://aquakarma974.over-blog.com/ Ex : Jardin vertical intérieur de 33 m3 d'Aquakarma 974]</ref>.
Le [[w:Gabion|gabionnage]] a encore donné lieu au XXème siècle à divers [[w:innovation|innovation]]s<ref>ex : CLAUZEL, L. (1963). ''[http://documents.irevues.inist.fr/bitstream/handle/2042/24557/RFF_1963_6_512.pdf?sequence=1? Un nouveau système de gabions: les coffres en treillis d'acier remplis en hérisson]''.</ref> et [[w:brevet (invention)|brevets]]<ref>ex : Hilfiker, W. K. (1991). U.S. Patent No. 5,076,735. Washington, DC: U.S. Patent and Trademark Office (brevet)</ref>, mais leur relative simplicité de fabrication peut permettre comme au [[w:fr:Burkina Faso|Burkina Faso]] de les faire fabriquer par des artisans locaux<ref>Royet, P. (1992). Les ouvrages en gabions, [http://agris.fao.org/agris-search/search.do?recordID=FR19960033446 fiche Agris-FAO]</ref>. On a notamment essayé d'y intégrer des fonctions de [[w:fr:Service écosystémique|services écosystémiques]] en les rendant parfois plus propices à la [[w:fr:Biodiversité|biodiversité]], par exemple en permettant leur colonisation par des [[w:racine|racine]]s d'[[w:racine|arbre]]s<ref>Koch, D. (1994). ''Essai d'intégration de la végétation dans les gabions sur un chantier de construction de route au Népal central'' (Doctoral dissertation).</ref>
{{clear}}
== Principe ==
[[File:04_-_Végétalis®_chevalets.jpg|thumb|upright=1|left|Des producteurs (ici ''murs végétalis®'') proposent des mélanges d'espèces et de variétés permettant une meilleure résistance aux maladies…]]
[[File:Greenbox®.jpg|thumb|250px|Module ''Greenbox®'']]
[[File:Végétalis® école archi.jpg|thumb|upright=1|Mur végétalis® de l'[[w:école d'architecture de Montpellier|école d'architecture de Montpellier]], don de la société ''Greenwall'']]
[[File:03_-_Cultures_végétalis.jpg|thumb|upright=1|Les plantes préparées sur une surface presque verticale auront un aspect plus naturel dès leur installation sur le mur (Cultures végétalis®)]]
Des murs ou parois végétalisées peuvent être aménagés tant à l'extérieur qu'à l'intérieur de bâtiments, avec ou sans source artificielle de lumière.
<br>Le principe s'appuie sur le fait qu'en l'absence d'intervention humaine, en présence d'air propre et d'une humidité suffisante de l'air, tout support tend à être naturellement colonisé par des bactéries ([[w:fr:Biofilm|biofilm]]), des [[w:fr:Algues|algue]]s, puis des [[w:mousse (botanique)|mousse]]s et des [[w:Lichen|lichen]]s, avant l'apparition de petites plantes, qui sont généralement aussi des épiphytes des arbres. Dans le cas où le mur reste sec, ou en atmosphère plus sèche, il peut également être colonisé par des plantes grimpantes ([[w:Lierre grimpant|lierre]], [[w:Vigne vierge|vigne vierge]] en [[w:Climat tempéré|climat tempéré]]).
<br>Plusieurs approches techniques existent, allant de l'insertion de plantes adaptées aux milieux secs et pauvres (crassulantes, cactées..) pour créer des structure de type ''« jardins de rocailles »'', à des techniques sophistiquées dites de "génie végétal" optimisant les conditions de colonisation et de pousse des plantes grâce à des supports de feutre synthétique dans lequel circule de l'eau enrichie en sels nutritifs.
Un grand nombre de plantes tropicales épiphytes ou poussant à l'ombre de la canopée se contentent de peu de lumière et de peu de nutriments.
== Types d'aménagement de façades ==
Il peut se faire soit à partir du sol directement, les racines de plantes grimpantes y puisant leur nourriture et l'eau, soit en intégrant la flore au bâtiment, via des balconnières, des jardinières, ou des systèmes plus complexe de murs végétaux tels que ceux de [[w:patrick Blanc|Patrick Blanc]].
'''Par exemple :''' Sur le mur porteur est placé une ossature métallique qui soutient une plaque de [[w:Chlorure de polyvinyle|PVC]] expansé de 10 mm d'épaisseur, sur laquelle sont agrafées deux couches de feutre de [[polyamide]] de 3 mm d'épaisseur chacune. Ces couches de feutre miment en quelque sorte les [[w:mousse (botanique)|mousse]]s qui se développent sur les parois rocheuses et qui servent de support aux [[w:Racine (botanique)|racines]] des plantes. Un réseau de tuyaux commandés par des électrovannes apporte une [[w:engrais|solution nutritive]] contenant les éléments minéraux nécessaires à la croissance des plantes. Le feutre s'imprègne de cette solution nutritive, qui redescend le long du mur par gravité. Les racines des plantes n'ont qu'à se servir, et l'eau en excès est recueillie en bas du mur par une gouttière, avant d'être réinjectée dans le réseau de tuyaux : le système fonctionne en circuit fermé.
C'est une variation inhabituelle d'une [[w:machine vivante|machine vivante]] : l'eau s'écoule sur une surface sur laquelle se développent de la [[w:mousse (botanique)|mousse]] ou d'autres plantes, quelques [[w:Arthropode|arthropodes]]s et des [[w:Bactérie|bactérie]]s, et est captée en bas du mur dans une [[w:Gouttière (architecture)|gouttière]], d'où elle est réinjectée en haut du mur.
== Les avantages ==
En plus de l'aspect esthétique, le mur végétalisé présente plusieurs avantages :
*Il permet une meilleure régulation thermique du bâtiment. En été, l'ensoleillement est réduit.
*L'[[w:évapotranspirationévapotranspiration]] du lierre ou d'autres grimpantes contribue au rafraîchissement de l'air et à une régulation de l'[[w:Hygrométrie|hygrométrie]]. En hiver, ce couvert végétal seul ne peut jouer un véritable rôle d'[[w:Isolation (construction)|isolant]], mais en asséchant les fondations et en protégeant les murs de la pluie (grâce à l'orientation des feuilles et à leur densité dans le cas du lierre), il les rend plus [[w:Isolant|isolant]]s.
*Il protège le bâtiment contre l'effet corrosif des pollutions urbaines ([[w:Pluie acide|pluie acide]], [[w:Pollution de l'air|pollution atmosphérique]]) et contre l’humidité (acide, en ville), en offrant une surface imperméable à la pluie. En effet, la disposition "en tuiles" des feuilles de certaines grimpantes, telles que le lierre, permet de protéger presque totalement le mur de la pluie.
*Les racines participent à l'assèchement du sol à proximité des fondations.
*La végétalisation des façades offre une surface végétale supplémentaire et significative pour l'épuration de l'air et la production d'oxygène.
*Certains [[w:mur anti-bruit|murs anti-bruit]] sont végétalisés, augmentant leur fonction dé-stressante (végétalis®, Le Prieuré, Héliotrope…). Le feuillage seul est réputé inefficace (une épaisseur de 10 m de feuillage d'arbres ne réduit un son puissant que d'à peine 1 dba), cependant le bruit du vent dans les feuilles et celui des oiseaux (comme celui des fontaines) ont des vertus psychologiquement apaisantes, et sans vraiment cacher le bruit ambiant, ils le rendent plus supportable.
== Utilisation du lierre ==
Le [[w:fr:Lierre grimpant|lierre]] est une plante particulièrement bien adaptée au verdissement des façades. Sauf dans le cas de murs maçonnés à la [[w:fr:Chaux (chimie)|Chaux hydraulique naturelle]] ou à la terre et qui seraient assez humides pour que les racines puissent y vivre, ce végétal n'abîme pas les façades, bien qu'il puisse endommager les peintures où ses crampons laissent des traces. Il est résistant aux conditions climatiques rudes ([[w:fr:inondation|inondation]], gel, [[w:fr:sécheresse|sécheresse]]...). Il reste vert toute l'année, ce qui lui permet de continuer à absorber du carbone pendant l'hiver, alors que la plupart des végétaux ont perdu leurs feuilles. La période de pollinisation du lierre se situe vers la fin de l'été. Il offre donc aux invertébrés pollinisateurs la possibilité de bénéficier d'un dernier approvisionnement en [[w:fr:Pollen|pollen]] en septembre-octobre-novembre. Puis ses fruits sont parmi les plus précoces (vers le mois de mars), constituent une nourriture de base pour les oiseaux frugivores (rentrant pour certains de [[w:migration des oiseaux|migration]]). De plus, comme d'autres espèces indigènes ([[w:fr:Fougère|fougère]]s, [[w:fr:Cymbalaire|cymbalaire]]), le lierre a une valeur esthétique.
D'autres espèces autochtones grimpantes couramment utilisées en Europe de l'Ouest sont la [[w:fr:Vigne vierge|vigne vierge]], le [[w:fr:Chèvrefeuille|chèvrefeuille]]...
== Entretien ==
Afin de préserver au maximum le potentiel de végétalisation des façades, le mur doit conserver ses irrégularités, sans altérer l'état général de la surface. Faire grimper du lierre sur un mur dont les joints sont abîmés (joints sableux) peut être dommageable pour la surface.
L'entretien des façades ne peut pas se faire à toutes les époques de l'année afin de respecter les rythmes de la faune et de la flore qui y auront trouvé refuge. Il faut éviter les périodes de [[w:nidification|nidification]] ou les périodes de froid hivernal pendant lesquelles la végétation sert d'abri pour de nombreux [[w:invertébré|invertébré]]s.
Afin de faciliter la [[w:végétalisation|végétalisation]] suivant un processus naturel, il faut conserver des îlots de végétation (mousse, fougères) lors de l'entretien des façades.
Une attention particulière doit être apportée à l’entretien des façades et structures végétalisées. Si les plantes grimpantes ou la flore des [[w:Toiture végétale|terrasses extensives]] sont rustiques et ne nécessitent ni arrosage ni engrais. Il faut respecter les points suivants :
*Les [[w:plante grimpante|plantes grimpantes]] ne doivent pas atteindre les tuiles, ardoises ni les [[w:Gouttière (architecture)|gouttière]]s. Si leurs feuilles mortes bouchaient ou freinaient l’évacuation des eaux pluviales, celles-ci pourraient déborder et s’écouler le long des façades, au risque d’altérer les matériaux, de favoriser la pénétration de racines et l'implantation de fougères, graminées, voire de plantes buissonnantes ou d'arbres dans les ciments de mauvaise qualité ou composés de chaux hydraulique naturelle, ou de terre.
**De la même façon, il faut tailler régulièrement les végétaux autour des ouvertures, prises d'air, cheminées, de manière que la végétation ne guide pas des espèces indésirables ou invasives vers les espaces intérieurs (insectes (comme les fourmis) ou araignées...). Un filtre de type moustiquaire peut protéger les prises d'air.
*Le pourtour des terrasses végétalisées doit être nettoyé ou inspecté une à 2 fois par an de manière à vérifier que les drains ne soient pas bouchés (par feuilles mortes, cadavres d'oiseaux, etc, ce qui vaut aussi pour les terrasses non végétalisées).
*Quelques plantes grimpantes, telles que la [[w:glycine (plante)|glycine]], peuvent s’enrouler autour des gouttières, des tuyauteries, et les compresser jusqu’à la rupture. Il faut donc contrôler, guider sélectionner ou adapter la végétalisation en fonction du type de mur ou de support.
Pour favoriser une [[w:Biodiversité|biodiversité]] aussi proche que possible du potentiel local, toutes les surfaces du bâti, autres que les vitres et les panneaux solaires peuvent être végétalisées.
== Précautions, sécurité ==
[[Image:GlycineGouttière.jpg|thumb|right|300px|Une [[w:Glycine|glycine]] enroulée autour d'une gouttière peut finir par la tordre ou l'écraser. Mieux vaut guider ce type de grimpante sur un support préparé pour elle.]]
L'aménageur doit prendre en compte les problèmes qui peuvent être posés par l'humidité (salissures par les spores de fougères, de mousses et de champignons, risques de court-circuit en cas d'éclairage artificiel, de chauffage, présence de pompes, etc.), et par le poids des végétaux qui grandissent.
Ces murs peuvent aussi être colonisés par une faune d'invertébrés tolérés ou souhaités en aquaterrarium, mais non désirés dans une habitation ou un lieu public.
Dans le cas de murs végétaux, le mur ou le support, s'ils ne sont pas conçus par l'architecte pour résister à l'eau enrichie de nutriments, doivent en être protégés.
Certains murs maçonnés à la terre ou à la chaux hydraulique doivent être protégés de la pénétration de racines susceptibles de les dégrader.
Un entretien et des vérifications régulières sont nécessaires.
En cas d'utilisation de plantes exotiques, afin d'éviter d'importer des organismes indésirables ou microbes pathogènes, il est recommandé de travailler avec des horticulteurs spécialisés et des plantes dont l'origine est traçable et légale.
== Les oiseaux ==
Le fait d'augmenter la biodiversité augmente aussi la présence des oiseaux. Or, les surfaces vitrées constituent un piège visuel pour l'avifaune qui percute des fenêtres de jour ou de nuit.
*L'oiseau peut être victime d'un effet miroir lorsque la vitre reflète le ciel.
*Il peut penser pouvoir traverser le bâtiment lorsqu'il aperçoit une autre ouverture dans le même axe.
*Il peut percuter une vitre invisible de type mur antibruit ou de type « balustrade vitrée » par exemple sur une terrasse.
*De nuit, des oiseaux en migration percutent fréquemment des fenêtres d'une pièce éclairée (c'est l'un des aspects de la [[w:pollution lumineuse|pollution lumineuse]].
La fréquence des collisions nocturnes avec des vitres éclairées peut être diminuée de 80 % par la fermeture d'un volet ou d'un rideau épais.
<br>Et de jour, on diminue fortement le risque de collision par l'apposition d'une silhouette noire représentant un oiseau de proie, encore plus efficacement si celle-ci est suspendue à un fil qui lui permet de bouger. Ces silhouettes sont commercialisées par différentes associations ou institutions. Elles ne gênent pas la faune locale qui s'y habitue et préviennent les collisions avec les oiseaux migrateurs ou de passage.
== Variantes intérieures ==
Une variante à la façade végétalisée est le mur intérieur végétalisé.
La seule contrainte supplémentaire concerne la [[w:éclairage nocturne|lumière]] qui doit être amenée en quantité et qualité suffisantes, et si possible orientée du haut vers le bas pour assurer une bonne croissance aux végétaux. Le mur végétalisé d'intérieur peut être construit dans une [[w:véranda|véranda]] ou sous une verrière, en prenant garde aux éventuelles surchauffes et aux problèmes éventuels liés à l'eau et à la condensation.
Une première manière de végétaliser le mur est de mettre sur la surface un substrat apte à être colonisé par les végétaux choisis. Ce substrat sera comparable à celui des toitures végétalisées, ou de type feutre synthétique associé à un système de pompe (éventuellement solaire) maintenant un écoulement d'eau le long du substrat qui sera progressivement colonisé par les végétaux qu'on y aura plantés.
Quelques exemples de réalisations intérieures innovantes :
<gallery>
Image:Bar végétalisé 2.JPG|<div style="text-align: center;">Bar végétalisé</div>
Image:Triptik.png|<div style="text-align: center;">Le tableau végétal</div>
Image:Mur végétal intérieur.jpg|<div style="text-align: center;">Un Mur intérieur</div>
</gallery>
{{message galerie}}
Il est aussi possible de planter des végétaux grimpants, buissonnants ou arbres dans le "vrai sol" ; Ainsi dans le lycée [[w:Haute qualité environnementale|HQE]] de Calais, des arbres ont été plantés sous les verrières intérieures, non dans des fosses qui nécessiterait un arrosage, mais dans le vrai sol réservé par l'architecte.
On peut aussi faire entrer le végétal (type lierre ou plante grimpante) par un orifice réservé en bas du mur, garni d'un isolant, tout en laissant ses racines s'épanouir dans le sol à l'extérieur. Les végétaux à crampons ou racines aériennes prennent appui sur la structure et colonisent progressivement le mur. Il faut cependant mettre en place un système permettant d'empêcher l'accès aux araignées, souris et autres indésirables par l'orifice d'accès du végétal. Ce système est le plus simple, car il ne nécessite quasiment pas d'entretien, si ce n'est une taille régulière pour éviter l'envahissement de la maison. En général, il n’est pas nécessaire de l'arroser puisque le végétal a ses racines à l'extérieur, sauf en cas de sécheresse prolongée.
L'intérêt principal du mur végétalisé peut être le [[w:renouvellement de l'air intérieur|renouvellement de l'air intérieur]] ou la [[w:phytoremédiation|phytoremédiation]]. Voir aussi le programme [[w:Phyt'air|Phyt'air]].
=== Le mobilier urbain végétalisé ===
[[Image:LierrePoteau.jpg|thumb|Poteau électrique et support de [[w:lampadaire|lampadaire]] couverts de lierre. <br />Sans remplacer un arbre, ce poteau ''« rembourse une partie de sa [[w:Dette écologique|dette écologique]] »'' en produisant de l'oxygène toute l'année, en produisant un pollen tardif (dernière nourriture des abeilles dans l'année) et en offrant « gîte et couvert » aux oiseaux et à d'autres animaux.]]
Pour pallier le manque d'arbres et de photosynthèse en milieu urbain, une grande partie du mobilier urbain pourrait être végétalisé :
* [[w:Poteau électrique|Poteau électrique]] ;
* [[w:Lampadaire|Lampadaire]] ;
* [[w:Banc public|Banc public]] ;
* [[w:Abribus|Abribus]], etc.
Plusieurs solutions sont possibles : plantations directement dans le sol lorsque c'est possible (végétalisation auto-entretenue) ou dans des bacs de volume variable en fonction de la taille de la structure (il faut alors arroser le végétal régulièrement, au moins les premières années).
Les [[w:toiture végétale|toitures-terrasses végétalisées]] peuvent également compléter ces dispositifs, ne nécessitant que peu d'entretien s'il s'agit d'une végétalisation extensive ([[w:sédum|sédum]]s..).
==Prospective ==
L'objectif de stopper la perte de biodiversité (objectif qui n'a pas été tenu dans les années 2010) implique de contribuer à la restaurer partout où cela se peut, dont en ville et dans ou sur le bâti;
(début d'article, non terminé. Aide bienvenue)
{{...}}
== Bibliographie ==
* Noël Dunnett ''Toits et murs végétaux'' ; Éd. du Rouergue, Rodez, 2008
* Jean-Michel Groult, ''Créer un mur végétal''/ Paris : Ulmer ; DL 2008
* Kindt, Agnes (Institut du Développement Durable et Responsable), Véronique DHAM (Gondwana), présentation ''[http://www.gecina.fr/fo/fileadmin/user_upload/Developpement%20durable/GECINALAB/2012/Horizons%20-Biodiversite-%2003%2004%2012.pdf La Biodiversité, semaine du développement durable]'', 3 avril 2012. IDDR Université catholique de Lille. Conférence Gecina
* Lewandowski, Delphine (2021) Étude et définition théoriques, techniques et biologiques d’un mur « biodiversitaire » – Un nouveau système de végétalisation vertical favorisant la biodiversité, thèse Paris Est, sous la direction de Robert Le Roy et Philippe Clergeau, www.theses.fr/s235700, en partenariat avec l’agence ChartierDalix, la plateforme Faire et le Pavillon de l’Arsenal, https://cesco.mnhn.fr/fr/actualites/un-mur-biodiversitaire-sinstalle-devant-le-laboratoire-6434.
== Notes et références pour ce sous-chapitre ==
<references />
[[Catégorie:Introduire la biodiversité dans la construction et l'urbanisme (livre)|L'enveloppe du bâti elle-même ]]
1949p8eql484iejay6q1r5st2zv42mj
Fonctionnement d'un ordinateur/Contrôleur mémoire externe
0
65796
764225
764180
2026-04-21T14:05:58Z
Mewtow
31375
764225
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les anciens contrôleurs mémoires étaient des composants séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande, le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings''est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits d'entrée BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Pour communiquer avec le processeur, il disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Précisémment, le 8206 était placé sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
8l5cml4mykebalycws2bcaabmxevgfs
764226
764225
2026-04-21T14:32:15Z
Mewtow
31375
/* Le contrôleur d'une DRAM simple, asynchrone */
764226
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le résultat est que la microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits d'entrée BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Pour communiquer avec le processeur, il disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Précisémment, le 8206 était placé sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
lbc1x3ce1n9y39u6vf1l29li2mcfyc8
764227
764226
2026-04-21T14:37:43Z
Mewtow
31375
/* Le générateur de timings et la traduction d'adresse */
764227
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le résultat est que la microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits d'entrée BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Pour communiquer avec le processeur, il disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Précisémment, le 8206 était placé sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
t41i0x3h5gyrt06xmea4v538184fjic
764228
764227
2026-04-21T14:39:08Z
Mewtow
31375
/* Exemple : l'Intel 8202-8203 */
764228
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits d'entrée BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse.
Pour communiquer avec le processeur, il disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Précisémment, le 8206 était placé sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
a65rqsdr4etla4o1pcxmgfrh4hxkgfe
764229
764228
2026-04-21T14:40:50Z
Mewtow
31375
/* Exemple : l'Intel 8202-8203 */
764229
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Précisémment, le 8206 était placé sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
0lh0yh2dt23rguso1nz7c194eovp8j9
764230
764229
2026-04-21T14:44:09Z
Mewtow
31375
/* L'Intel 8207 : ECC et systèmes bi-processeurs */
764230
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
Un point très important est qu'il avait deux ports séparés, pour fonctionner dans un '''système à deux processeurs'''. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ptuewcfd9lad8bfqfjc4iq68rvvdkqy
764232
764230
2026-04-21T14:57:20Z
Mewtow
31375
/* L'Intel 8207 : ECC et systèmes bi-processeurs */
764232
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
932qoc2nxfl47xsykgfc9mo69xb9vym
764235
764232
2026-04-21T15:03:04Z
Mewtow
31375
/* Le contrôleur d'une DRAM simple, asynchrone */
764235
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur dédié pour le rafraichissement des lignes, et qu'il active la circuiterie pour envoyer un signal de rafraichissement à intervalles réguliers. Il peut aussi y avoir un système à base d'interruptions pour rafraichir la mémoire régulièrement, ou un système de rafraichissement logiciel. Pour éviter cela, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
69e6k6sl4h3ah0i7tbi2lc68v5c9kys
764236
764235
2026-04-21T15:05:43Z
Mewtow
31375
/* Le rafraichissement mémoire */
764236
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur pour le rafraichissement des lignes et envoie des requêtes de rafraichissement à intervalles réguliers. Il peut utiliser des interruptions pour rafraichir la mémoire régulièrement, ou déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Pour faire plus simple, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
pxgi4d3c3f148nxrghp3szpowoyuxv2
764238
764236
2026-04-21T15:18:16Z
Mewtow
31375
/* L'Intel 8207 : ECC et systèmes bi-processeurs */
764238
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur pour le rafraichissement des lignes et envoie des requêtes de rafraichissement à intervalles réguliers. Il peut utiliser des interruptions pour rafraichir la mémoire régulièrement, ou déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Pour faire plus simple, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Il est très utile pour gérer des configurations multiprocesseurs, aussi. Un processeur peut aussi démarrer un accès mémoire, le second processeur saura qu'il doit attendre que l'accès soit terminé pour que ce soit son tour. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
itn4rfcolalnf32sulwdchce1580dmu
764240
764238
2026-04-21T15:20:32Z
Mewtow
31375
/* Exemple : l'Intel 8202-8203 */
764240
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur pour le rafraichissement des lignes et envoie des requêtes de rafraichissement à intervalles réguliers. Il peut utiliser des interruptions pour rafraichir la mémoire régulièrement, ou déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Pour faire plus simple, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
4wbz610a1isl9spa0a50j9ma33et17e
764244
764240
2026-04-21T16:27:17Z
Mewtow
31375
/* L'interface d'un contrôleur de DRAM asynchrone */
764244
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
Pour rappel, la gestion du rafraichissement mémoire est dévolue soit au processeur, soit à la DRAM elle-même, soit au contrôleur mémoire. Quand elle est le fait du processeur, celui-ci incorpore un compteur pour le rafraichissement des lignes et envoie des requêtes de rafraichissement à intervalles réguliers. Il peut utiliser des interruptions pour rafraichir la mémoire régulièrement, ou déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Pour faire plus simple, on préfère déléguer le rafraichissement au contrôleur mémoire externe.
S'il gère le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements. Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
53733bdj6v9r8p8x0ugtw3kh25825pm
764246
764244
2026-04-21T16:30:05Z
Mewtow
31375
/* Le rafraichissement mémoire */
764246
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
===L'Intel 8207 : ECC et systèmes bi-processeurs===
L'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM.
La '''gestion de l'ECC''' était partiellement prise en compte dans le contrôleur mémoire. Il avait besoin d'être couplé avec un Intel 8206 pour faire les calculs d'ECC. C'est le 8206 qui détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Il y avait un 8206 séparé du 8207, car les deux ne sont pas placés au même endroit. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était ps pratique car le contrôleur mémoire était trop simple pour ça.
Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Par contre, le 8026 a besoin de récupérer la donnée lue pour détecter/corriger les erreurs, ce qui fait qu'il est connecté directement sur le bus de données. Il prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
rjtq6lohmcs8c4sybjcn3wn2kqvq4vw
764250
764246
2026-04-21T16:54:00Z
Mewtow
31375
/* L'Intel 8207 : ECC et systèmes bi-processeurs */
764250
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206.
Le 8026 prenait en entrée : 16 bits de données entrée et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela. Sur les contrôleurs mémoire modernes, les deux circuits seraient fusionnés, l'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
7p1lsdk6u6eoc4v7st9a222v3xil1ci
764251
764250
2026-04-21T16:55:22Z
Mewtow
31375
/* La gestion de l'ECC et le contrôleur mémoire */
764251
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
===Les contrôleurs mémoires multiports avec une DRAM monoport===
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
leao2hf5hmuqz99lt1k0rlfcz76xeqk
764253
764251
2026-04-21T17:00:51Z
Mewtow
31375
/* La gestion de l'ECC et le contrôleur mémoire */
764253
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports avec une DRAM monoport===
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
es99s2q8bwfeh1nawrgifxeyuoyl80e
764255
764253
2026-04-21T17:04:42Z
Mewtow
31375
/* Les contrôleurs mémoire synchrone avec une RAM asynchrone */
764255
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2mb|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports avec une DRAM monoport===
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
s2j7ye8mnj9hgihfqi7nz8nftv31zt4
764256
764255
2026-04-21T17:04:50Z
Mewtow
31375
/* Les contrôleurs mémoire synchrone avec une RAM asynchrone */
764256
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports avec une DRAM monoport===
Le 8207 était un '''contrôleur mémoire multiport''', à savoir qu'il avait deux ports séparés. Il pouvait ainsi simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Les accès mémoire sur les deux ports étaient en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Le 8207 était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
1ifbu49a1dtdxicxkwb16iptooad38v
764257
764256
2026-04-21T17:07:51Z
Mewtow
31375
/* Les contrôleurs mémoires multiports avec une DRAM monoport */
764257
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, toutes les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalmités bien plus intéressante, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone avec une RAM asynchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC et le contrôleur mémoire===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en-dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Ils fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports avec une DRAM monoport===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Il peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elle était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé a la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates.Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
96013ofpah1g5cs605qe03qxf7iav8g
764258
764257
2026-04-21T17:15:11Z
Mewtow
31375
/* Le contrôleur d'une DRAM simple, asynchrone */
764258
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire pour une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
d8liz1tbfohq63jgwsaxpwtimcznd5r
764259
764258
2026-04-21T17:30:40Z
Mewtow
31375
/* Le contrôleur mémoire pour une SDRAM */
764259
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
La '''gestion de l'ECC''' peut elle aussi être partiellement prise en compte dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit en question peut, comme les registres synchrones, être intégré dans le contrôleur mémoire ou en dehors. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
Sur les contrôleurs mémoire modernes, le 8207 et le 8206 seraient fusionnés. L'ECC serait géré par le contrôleur mémoire lui-même. Mais à l'époque, ce n'était pas pratique car le contrôleur mémoire était trop simple pour ça.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
d1m7xs5maocddx269j1dyudk3ugwn6z
764260
764259
2026-04-21T18:04:02Z
Mewtow
31375
/* La gestion de l'ECC */
764260
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ktndzinp5hcf4nq0wc2mfccaidoniuh
764264
764260
2026-04-21T19:45:27Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764264
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
gjseqn04ovuuaxo3puweewyip70oeqy
764267
764264
2026-04-21T20:39:38Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM */
764267
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès succesifs à la même ligne, à dfes colonnes différentes.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Le contrôleur mémoire doit être adapté pour cela. Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
k2qvul3wxpmso1eaifoxe65f8x8bqh0
764269
764267
2026-04-21T20:47:32Z
Mewtow
31375
/* Le contrôleur mémoire d'une DRAM Fast Page Mode */
764269
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès succesifs à la même ligne, à dfes colonnes différentes.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit être adapté pour cela. Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les mémoires en mode quartet/colonne statique===
Avec les '''mémoires en mode quartet''' et en mode '''colone statique''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante.L’implémentation est très similaire à celle d'une mémoire FPM, il suffit juste de modifier le séquenceur mémoire, et de mémoriser l'adresse de colonne dans un registre compteur. Le séquenceur mémoire incrémente le registre de l'adresse de colonne pour passer à la suivante.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
bntjd6yvcceuqyqm075g09l5s4nbqqy
764270
764269
2026-04-21T20:47:52Z
Mewtow
31375
/* Le contrôleur mémoire d'une DRAM Fast Page Mode */
764270
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les mémoires en mode quartet/colonne statique===
Avec les '''mémoires en mode quartet''' et en mode '''colone statique''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante.L’implémentation est très similaire à celle d'une mémoire FPM, il suffit juste de modifier le séquenceur mémoire, et de mémoriser l'adresse de colonne dans un registre compteur. Le séquenceur mémoire incrémente le registre de l'adresse de colonne pour passer à la suivante.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
4nxsjumercb9w95e2qathw1kevdhhim
764271
764270
2026-04-21T20:51:07Z
Mewtow
31375
/* Les mémoires en mode quartet/colonne statique */
764271
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
qjslgngcc59qa22nlr4j37rk2848eqy
764272
764271
2026-04-21T20:51:14Z
Mewtow
31375
/* Le contrôleur mémoire d'une DRAM Fast Page Mode */
764272
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''' et en mode '''colone statique''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Les mémoires en mode rafale et en mode colonne statique se passent complétement des changements de CAS entre chaque colonne. Le séquenceur mémoire a juste à être adapté pour ça.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
4wmlx77cv43ljan6taavkcbkbwmdkmm
764273
764272
2026-04-21T20:51:49Z
Mewtow
31375
/* Le contrôleur mémoire d'une DRAM Fast Page Mode */
764273
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Les '''mémoires en mode rafale''' et en mode '''colonne statique''' se passent complétement des changements de CAS entre chaque colonne. Le séquenceur mémoire a juste à être adapté pour ça.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
fndverqcciap6kwvdzpaijul84oun6j
764274
764273
2026-04-21T20:52:27Z
Mewtow
31375
/* Le contrôleur mémoire d'une DRAM Fast Page Mode */
764274
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Dans le cas le plus simple, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès mémoire est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge'', ou encore '''politique de la page fermée'''.
Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. Fermer celle-ci pour la réactiver au cycle suivant est évident contreproductif. Il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'''open page autoprecharge'', ou encore '''politique de la page ouverte'''. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne.
* Dans le premier cas, on doit juste changer de colonne : c'est un '''succès de tampon de ligne'''. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA. On observe donc un gain signifiant comparé à la politique de la page fermée dans ce cas précis.
* Dans le second cas, c'est un '''défaut de tampon de ligne''' et il faut procéder comme avec la politique de la page fermée, à savoir vider le tampon de ligne avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
qjslgngcc59qa22nlr4j37rk2848eqy
764276
764274
2026-04-21T21:00:11Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764276
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
o1137tq715upwffn1kgo4418o55msw4
764277
764276
2026-04-21T21:02:07Z
Mewtow
31375
/* Les succès et défauts de page */
764277
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Détecter un succès/défaut de tampon de ligne n'est pas très compliqué. Le séquenceur mémoire a juste à se souvenir des lignes et banques actives avec une petite mémoire : la '''table des banques'''. Pour détecter un succès ou un défaut, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : c'est un succès si c'est le cas, un défaut sinon.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la '''table des banques''', aussi appelée ''bank status memory''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
0xzi8ae1pg1650x3lb4ro6utmgkt0qn
764278
764277
2026-04-21T21:04:13Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764278
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente, encore une fois avec l'aide de la '''table des banques'''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
3qvr8e6vum9mqx94ctenxrc8hbwofpq
764279
764278
2026-04-21T21:06:56Z
Mewtow
31375
/* Les succès et défauts de page avec une seule banque */
764279
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur.
c'est un succès si c'est le cas, un défaut sinon.
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente, encore une fois avec l'aide de la '''table des banques'''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
dttwoblsvp8tljwq4ylik5gizw8eiss
764280
764279
2026-04-21T21:07:14Z
Mewtow
31375
/* Les succès et défauts de page avec une plusieurs banques */
764280
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente, encore une fois avec l'aide de la '''table des banques'''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
c1v0r3r4ht4vzrg9mfz3qoqt5ftvx8t
764281
764280
2026-04-21T21:12:52Z
Mewtow
31375
/* Les succès et défauts de page avec une plusieurs banques */
764281
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne. A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente, encore une fois avec l'aide de la '''table des banques'''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
80zpmjfh9pdydfirfmrtf2u4hm3hgp5
764282
764281
2026-04-21T21:14:33Z
Mewtow
31375
/* Les succès et défauts de page avec une seule banque */
764282
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le tampon de ligne et les lignes des accès en attente, encore une fois avec l'aide de la '''table des banques'''. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la table des banques, le résultat étant comparé avec le numéro de ligne de l'accès.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
oyz9ektl6wa7jlg0c2gqb8ddjf0iwqo
764283
764282
2026-04-21T21:16:27Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764283
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. On appelle cette méthode la close ''page autoprecharge''. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est. Les performances sont nettement meilleures, le seul désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
9bcx63egkj63sj6o6mjhy76jf6qbrh4
764285
764283
2026-04-21T21:30:30Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764285
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page. De plus, il profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE, la PRECHARGE étant exécutée automatiquement après la lecture/écriture. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est. Les performances sont nettement meilleures, le seul désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ena86vaamx3v1kpvoyglquhappikp8v
764287
764285
2026-04-21T21:34:13Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764287
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page. De plus, il profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est. Les performances sont nettement meilleures, le seul désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
kc39sws7e4okuwa3r24ay8veukarqp7
764289
764287
2026-04-21T21:41:18Z
Mewtow
31375
/* Le séquenceurs mémoire pour des SDRAM */
764289
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page. De plus, il profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est. Les performances sont nettement meilleures, le seul désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
0evoskfktbr7lknldn2x0oxd7p0yw5f
764290
764289
2026-04-21T21:46:00Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764290
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est. Les performances sont nettement meilleures, le seul désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
nkqangzxy6lpt1or95rpvv0w0i19fyg
764291
764290
2026-04-21T21:50:51Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764291
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Les performances sont nettement meilleures, si les accès mémoire tendent à réutiliser la même ligne assez fréquemment. Mais si les accès mémoire sont aléatoires, et accèdent à des lignes différentes, les performances sont moins bonnes. En effet, le contrôleur mémoire doit envoyer des commandes PRECHARGE, en cas de défaut de page. La subtilité est que là où la politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre, avant que son adresse soit analysée. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques, comme vu plus haut dans la section sur les mémoires FPM.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
imywh4dw8q6thpqpu5r4msgqxfyp3au
764292
764291
2026-04-21T21:51:27Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764292
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, si les accès mémoire tendent à réutiliser la même ligne assez fréquemment. Mais si les accès mémoire sont aléatoires, les performances sont moins bonnes.
En effet, le contrôleur mémoire doit envoyer des commandes PRECHARGE, en cas de défaut de page. La subtilité est que là où la politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre, avant que son adresse soit analysée. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard.
Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. Elles décident s'il faut maintenir ouverte la ligne en regardant les accès mémoire en attente, dans la mémoire FIFO avant le séquenceur mémoire. Pour implémenter ces techniques, le contrôleur extrait les numéros de banque et de ligne des accès en attente, pour adresser la table des banques.
La politique la plus simple laisse la ligne ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
1a648pmw5oo8l41ht05mlwwvjixyxwq
764293
764292
2026-04-21T21:57:25Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764293
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, si les accès mémoire tendent à réutiliser la même ligne assez fréquemment. Mais si les accès mémoire sont aléatoires, les performances sont moins bonnes.
En effet, le contrôleur mémoire doit envoyer des commandes PRECHARGE, en cas de défaut de page. La subtilité est que là où la politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre, avant que son adresse soit analysée. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard.
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement marche très bien avec la politique à page ouverte ou les techniques assimilées. Elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
3bxyx9dh223r25iq9lfikemg36akazg
764294
764293
2026-04-21T21:58:00Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764294
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, si les accès mémoire tendent à réutiliser la même ligne assez fréquemment. Mais si les accès mémoire sont aléatoires, les performances sont moins bonnes.
En effet, le contrôleur mémoire doit envoyer des commandes PRECHARGE, en cas de défaut de page. La subtilité est que là où la politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre, avant que son adresse soit analysée. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard.
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
r0vfik6hkrhi21wq1a9o06so9mw3fjp
764295
764294
2026-04-21T22:05:41Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764295
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Niveau consommation d'énergie, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Si la mémoire n'est pas utilisée, on fait face à deux choix : soit on ferme la ligne courante en attendat l'accès suivant, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Elle tend à économiser de l'énergie.
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
14o9jsbshiqja8ippfdlyv0l0g8nbvu
764296
764295
2026-04-21T22:11:48Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764296
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des acc_s mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Si la mémoire n'est pas utilisée, on fait face à deux choix : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Pour aller plus loin, les techniques prédictives tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
54xr16ynjzzt5wg8ym5f7j3yj49wr00
764299
764296
2026-04-21T22:25:35Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764299
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des acc_s mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
g5mc0mxp7ieaicirtk389r4xs4gec92
764300
764299
2026-04-21T22:25:59Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764300
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
3q0lacifc89ja508sqoadxz41av4kgt
764301
764300
2026-04-21T22:26:16Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM */
764301
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
De plus, les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
htnti349q3dkoo0mszuxq9tel4i9ru3
764302
764301
2026-04-21T22:26:35Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM */
764302
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps. Mais on peut se poser la question : dans quelles situations on peut se retrouver avec plusieurs accès mémoire simultanés ?
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
sj3d6p72tdf6xza4kk24yl76tr1m2gi
764303
764302
2026-04-21T22:26:55Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM */
764303
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent traite une commande READ. La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ge8r1epx3j5x0ht7hp3bb7zsusvl6tw
764304
764303
2026-04-21T22:28:47Z
Mewtow
31375
/* Le séquenceurs mémoire pour des SDRAM */
764304
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-tutilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
gxy06emjo7jgbpzbj7ujosqzskdgjx0
764305
764304
2026-04-21T22:36:33Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764305
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrétement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le controleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
7ew8i3sdiw63frabq22mx2h45gj7na3
764306
764305
2026-04-21T22:37:48Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764306
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Ce ré-ordonnancement cherche à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination, ce qui demande une file d'attente pour chaque banque.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
bf5k0lp3n5e5c4mm85sshlofo4x5yc7
764307
764306
2026-04-21T22:45:08Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764307
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi chercher à profiter au mieux de la politique à page ouverte, elles ne servent à rien si le séquenceur utilise une politique de la page fermée. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer. Les commandes sont réorganisés de manière à regrouper les accès dans la même ligne, afin qu'ils soient consécutifs s'ils ne l'étaient pas avant ré-ordonnancement.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
3192wwbrtlh6mh6cenn88toreb8jloe
764308
764307
2026-04-21T22:54:13Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764308
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Mais cette optimisation a plusieurs problèmes. Déjà, si les accès sont des lectures, cela signifie que les lectures seront effectuées dans le désordre. Mais le processeur s'attend à recevoir les données lues dans l'ordre d'envoi des commandes. Les données lues sont donc remises en ordre avant d'être envoyées au processeur. Pour cela, elles sont mémorisées dans la SDRAM et envoyées sur le bus de données dans l'ordre initial. En clair : des accès à une même ligne sont effectués en avance, mais l'envoi sur le bus de données se fait dans le bon ordre.
Ensuite, l'optimisation peut pose problème si de nouveaux accès arrivent dans la file d'attente. Si de nouveaux accès à la même ligne arrivent sans cesse, ils passeront devant les autres, laissant certains accès en attente permanente. Le cas est irrélaiste, mais le cas concret le plus proche est que certains accès sont effectués en retard, parfois avec beaucoup de retards. Pour éviter cela, il faut ajouter des limites dans le nombre d'accès consécutifs à une même ligne, si d'autres accès sont en attente.
Pour réordonnancer les accès mémoire, le séquenceur vérifie si il y a des dépendances entre les accès mémoire. Les dépendances en question n'apparaissent que si les accès se font à une même adresse. Si tous les accès mémoire se font à des adresses différentes, il n'y a pas de dépendances et ont peut, en théorie, faire les accès dans n'importe quel ordre. Le tout est juste que le séquenceur remette les données lues dans l'ordre demandé par le processeur et communique ces données lues dans cet ordre au processeur. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. le cas réellement bloquant, qui empêche toute ré-ordonnancement, est le cas où une lecture lit une donnée écrite par une écriture précédente. Dans ce cas, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
p8njm2rf5wgktrcnsu5m8neq4jqm3me
764309
764308
2026-04-21T22:58:26Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764309
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Mais cette optimisation a plusieurs problèmes. Déjà, si les accès sont des lectures, cela signifie que les lectures seront effectuées dans le désordre. Mais le processeur s'attend à recevoir les données lues dans l'ordre d'envoi des commandes. Les données lues sont donc remises en ordre avant d'être envoyées au processeur. Pour cela, elles sont mémorisées dans la SDRAM et envoyées sur le bus de données dans l'ordre initial. En clair : des accès à une même ligne sont effectués en avance, mais l'envoi sur le bus de données se fait dans le bon ordre.
Ensuite, l'optimisation peut pose problème si de nouveaux accès arrivent dans la file d'attente. Si de nouveaux accès à la même ligne arrivent sans cesse, ils passeront devant les autres, laissant certains accès en attente permanente. Le cas est irréaliste, mais le cas concret le plus proche est que certains accès sont effectués en retard, parfois avec beaucoup de retards. Pour éviter cela, il faut ajouter des limites dans le nombre d'accès consécutifs à une même ligne, si d'autres accès sont en attente.
Enfin, il faut éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre, tant que les lectures sont remises en ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. C'est le seul cas réellement bloquant, qui empêche toute ré-ordonnancement. Par exemple, si une lecture lit une donnée écrite par une écriture précédente, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
3guaug0yvc3t5gacuf7v881jpn1t4b9
764310
764309
2026-04-21T23:21:12Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764310
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Cependant, les possibilités sont fortement limitées, car cette optimisation a plusieurs problèmes. Déjà, le processeur s'attend à recevoir les données lues dans l'ordre d'envoi des commandes. Impossible donc de changer l'ordre des lectures, qui doivent s'exécuter dans l'ordre d'arrivée. Pour ce qui est des écritures, le processeur ne les voit pas, il n'a aucune idée de quand elles s'exécutent, ce qui fait que les réorganisations possibles impliquent surtout les écritures. Le seul cas où l'ordre des écritures importe est quand on a des lectures et écritures à la même adresse.
En effet, il faut éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre, tant que les lectures sont remises en ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. C'est le seul cas réellement bloquant, qui empêche toute ré-ordonnancement. Par exemple, si une lecture lit une donnée écrite par une écriture précédente, la lecture doit avoir lieu après l'écriture.
Une première solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
Une seconde solution consiste à effectuer les lectures en priorité, quitte à mettre en attente les écritures. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée pas encore écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative. Cette solution a pour avantage de faciliter l'implémentation de la technique précédente. Séparer les lectures et écritures facilite la fusion des lectures en mode rafale, idem pour les écritures.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
jlhg5fkcnna3ysbzhs5gfyh0voq9j9i
764311
764310
2026-04-21T23:30:11Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764311
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Cependant, les possibilités sont fortement limitées, car cette optimisation a plusieurs problèmes. Déjà, le processeur s'attend à recevoir les données lues dans l'ordre d'envoi des commandes. Impossible donc de changer l'ordre des lectures, qui doivent s'exécuter dans l'ordre d'arrivée. Pour ce qui est des écritures, le processeur ne les voit pas, il n'a aucune idée de quand elles s'exécutent, ce qui fait que les réorganisations possibles impliquent surtout les écritures. Le seul cas où l'ordre des écritures importe est quand on a des lectures et écritures à la même adresse.
En effet, il faut éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre, tant que les lectures sont remises en ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. C'est le seul cas réellement bloquant, qui empêche toute ré-ordonnancement. Par exemple, si une lecture lit une donnée écrite par une écriture précédente, la lecture doit avoir lieu après l'écriture.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais si les trois accès étaient trois lectures, on n'aurait pas pu faire la réorganisation. le processeur aurait vu des lectures interverties, vu que le contrôleur mémoire n'a aucun moyen pour remettre les données lues dans le bon ordre.
L'implémentation de cette technique modifie la mémoire FIFO qui met les accès mémoire en attente. L'idée est d'utiliser une FIFO séparée pour les lectures et pour les écritures. Elle effectue les lectures en priorité, quitte à mettre en attente les écritures. Il faut cependant détecter un cas problématique : une lecture suit une écriture à la même adresse mémoire. Une telle situation est détéctée quand on veut émettre la lecture vers la SDRAM. Le controleur vérifie s'il y a une écriture en attente à la même ligne que la lecture. Dans ce cas, l'écriture est exécutée immédiatement, avant la lecture.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre optimisation regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ln26xf6ff1pvqaqzrscpmyz19yg18gq
764312
764311
2026-04-21T23:50:48Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764312
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
Le seul conflit est que les lectures doivent se faire dans le bon ordre du point de vue du processeur. Par exemple, imaginez que l'on ait deux lectures consécutives. La première fait un défaut de page, la seconde fait un succès de page. La seconde lecture étant plus rapide que la première, il se peut que la seconde termine avant la première. Ou encore, il se peut qu'elles cherchent à envoyer la donnée sur le bus de données en même temps. Il faut une intervention du séquenceur mémoire, pour éviter ce genre de problème. Il lui suffit de retarder certaines commandes, afin de faire en sorte que la banque fournisse son résultat au bon moment.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides.
Un point important est que le contrôleur mémoire ne remet pas vraiment les accès mémoire dans l'ordre. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lecture,s il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation matérielle est généralement assez simple : il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
Il faut cependant prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Une implémentation simple modifie la mémoire FIFO qui met les accès mémoire en attente. L'idée est d'utiliser une FIFO séparée pour les lectures et pour les écritures. Elle effectue les lectures en priorité, quitte à mettre en attente les écritures. En général, le contrôleur mémoire attend que la file d'écriture soit bien pleine pour toutes les exécuter en bloc. Il faut cependant détecter un cas problématique : une lecture suit une écriture à la même adresse mémoire. Une telle situation est détéctée quand on veut émettre la lecture vers la SDRAM. Le controleur vérifie s'il y a une écriture en attente à la même ligne que la lecture. Dans ce cas, l'écriture est exécutée immédiatement, avant la lecture.
[[File:Double file d'attente pour les lectures et écritures.png|centre|vignette|upright=2.5|Double file d'attente pour les lectures et écritures.]]
Une autre optimisation regrouper plusieurs accès à des données successives en un seul accès en rafale. Le séquenceur analyse les commandes mises en attente et détecte si plusieurs commandes consécutives se font à des adresses consécutives. Si c'est le cas, il fusionne ces commandes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ezb0hx9d4xmiwqatshddfv67mi17zhw
764313
764312
2026-04-21T23:59:41Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764313
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Un point important est que le contrôleur mémoire ne remet pas vraiment les accès mémoire dans l'ordre. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lecture,s il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation matérielle est généralement assez simple : il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
dla9rtypi1vl1hbjwu3vmn01kgy58u7
764314
764313
2026-04-22T00:01:03Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764314
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. En soi, cela peut paraitre un peu surprenant, mais l'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Un point important est que le contrôleur mémoire ne remet pas vraiment les accès mémoire dans l'ordre. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lecture,s il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation matérielle est généralement assez simple : il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
8yjhx6ppcm3kzhzpm23borxudn551mg
764315
764314
2026-04-22T00:02:33Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764315
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour des SDRAM===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit une requête du processeur en une séquence de commandes envoyées à des timings bien précis. Simplement, la machine à état est plus complexe. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, avec son compteur d'adresse et son ''timer'' de rafraichissement.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Le séquenceur mémoire décide s'il faut ajouter ou non des commandes PRECHARGE. Certains accès demandent des commandes PRECHARGE alors que d'autres peuvent s'en passer. Et c'est le séquenceur mémoire qui décide s'il faut ajouter ou non des commandes PRECHARGE. Le cas classiques est celui de deux accès consécutifs, qui atterrissent dans une même ligne : le second accès n'a pas besoin de commande PRECHARGE. D'ailleurs, quand on accède à des données consécutives, on a juste à changer l'adresse de la colonne : pas besoin d'envoyer de commande ACT pour changer de ligne. Mais cela demande que le séquenceur détecte la situation, à savoir que deux accès consécutifs se font dans la même ligne, sans usage du mode rafale. Nous détaillerons cela plus bas, dans une section dédiée.
Les SDRAM sont capables d'accepter plusieurs accès mémoire en même temps, à condition qu'elles soient dans des étapes différentes. Par exemple, on peut envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état est rendue encore plus complexe par cette possibilité, car il faut tenir compte de toutes les possibilités, y compris celles avec deux accès qui se passent en même temps.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Quand deux accès consécutifs se font dans la même ligne, les SDRAM ne ferment pas la ligne et se contente d'envoyer des adresses de colonne. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes.
Du moins, c'est le cas si le séquenceur mémoire est coopératif. Le séquenceur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le tampon de ligne. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode est adaptée à des accès aléatoires, mais réduit grandement les performances pour les accès à des adresses consécutives. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
La '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyée, seules la commandes READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont nettement meilleures, à condition que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée des commande READ et WRITE précédentes. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante, soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution entraine une petite perte de performance si les succès de page sont courants, mais améliore les performances s'ils sont rares. Par contre, elle tend à économiser de l'énergie. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Avec la nuance que rouvrir une ligne tend aussi à consommer de l'énergie.
Les contrôleurs mémoires basiques gérent une mémoire ''idle'' utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. Elles peuvent se tromper, mais une erreur de prédiction est corrigée en envoyant des commandes PRECHARGE au bon moment. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution regarde le dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture.
* Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon.
* Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant.
* Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du tampon de ligne, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
qrpdigd1zlhvu65k3lkffxafm9ktfjv
764316
764315
2026-04-22T00:39:23Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM */
764316
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois, sauf si des optimisations comme le ''pipelining'' sont implémentées. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Le fait de laisser le processeur faire du travail dans son coin est lié à une optimisation : les '''lectures/écritures non-bloquantes'''. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
8sy63qbta1855mvynzqz4gtnkb92eev
764317
764316
2026-04-22T00:43:35Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764317
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===Les ''wait state''===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
==Les contrôleurs mémoires haute performance==
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, les deux fonctionnant en tandem.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les '''lectures/écritures non-bloquantes''' sont une optimisation des processeurs modernes. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ldelp8abfatpd0ocyscmb7rtpa9keyp
764318
764317
2026-04-22T00:43:48Z
Mewtow
31375
/* Les contrôleurs mémoires haute performance */
764318
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
===Les ''wait state''===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
==Les contrôleurs mémoires haute performance==
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, les deux fonctionnant en tandem. Nous allons les détailler dans ce qui suit.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les '''lectures/écritures non-bloquantes''' sont une optimisation des processeurs modernes. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
0c09x0sme4so78wbt6phj4fe1qm77bd
764319
764318
2026-04-22T00:45:29Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM ou d'une DDR */
764319
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
==Les contrôleurs mémoires haute performance==
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, les deux fonctionnant en tandem. Nous allons les détailler dans ce qui suit.
===La mise en attente des accès mémoire===
Avec le 8207, nous avons vu que le contrôleur mémoire pouvait accepter deux accès mémoire simultanés, provenant de deux processeurs. Par contre, il exécute ces accès mémoire un à la fois. Il se trouve que la même chose peut arriver, mais avec un seul processeur.
Les '''lectures/écritures non-bloquantes''' sont une optimisation des processeurs modernes. Avec elles, le processeur ne se bloque pas lors d'un accès mémoire, sous certaines conditions. Une instruction de lecture ou d'écriture est toujours suivie par d'autres instructions, généralement des calculs ou des branchements. Et il est fréquent que ces instructions soient indépendantes de la lecture/écriture. Si c'est le cas, le processeur les exécute en avance, pendant que l'accès mémoire est en cours. Pour une écriture, le processeur envoie l'écriture au contrôleur mémoire et continue d'exécuter son programme, sans attendre que l'écriture soit terminée. Il en est de même pour les lectures : les processeurs modernes exécutent les instructions suivant la lecture en attendant que celle-ci fournisse son résultat.
Et parmi les instructions suivantes, il peut y avoir d'autres lectures ou écritures. Le résultat est que, pendant un accès mémoire d'une centaine de cycles, le processeur peut envoyer plusieurs lectures/écritures successives au contrôleur mémoire. Le contrôleur mémoire peut alors gérer cela de deux manières : soit il n'exécute qu'un seul accès mémoire à la fois, soit il accepte ces accès mémoire supplémentaires et il les met en attente.
Dans le premier cas, le contrôleur mémoire bloque dès qu'on lui demande de faire un second accès mémoire. Le processeur est alors soit bloqué, soit il met en attente cet accès mémoire de lui-même, dans des registres internes. Il doit pour cela incorporer des mécanismes de mise en attente, internes au processeur. Nous décrirons ces mécanismes dans un chapitre dédié, à la fin de ce wikilivre.
Dans le second cas, le contrôleur mémoire accepte plusieurs accès mémoire simultanés. Et là, il y a deux mécanismes pour gérer ces accès simultanés. Il peut accepter ces accès simultanés, mais il ne les exécute qu'un seul à la fois. Les autres accès sont mis en attente et seront exécutés dès que l'accès précédent est terminé. Une autre solution exécute plusieurs acc_s mémoire en même temps, à condition qu'ils se fassent soit dans des banques différentes, soit dans la même banque mais à des étapes différentes. Dans les deux cas, on parle de '''''pipelining'' mémoire'''.
Dans les deux cas, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Quelques optimisations permettent cependant de changer l'ordre des accès mémoire, pour gagner en performance, comme on le verra plus bas. Évidemment, cette réorganisation ne se voit pas du côté du processeur, car le contrôleur remet les accès dans l'ordre et envoie les données lues au processeur dans l'ordre des requêtes processeur. Il reçoit les données lues depuis la mémoire et les remet dans l'ordre de lecture demandé par le processeur. Mais nous reparlerons de ces capacités d'ordonnancement plus bas.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
ozox8ykfkf0tkdhzicg5h12f6cy01d9
764320
764319
2026-04-22T00:54:04Z
Mewtow
31375
/* Les contrôleurs mémoires haute performance */
764320
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire. Et on trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur, dont on expliquera l'utilité plus bas.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
cac4duu3vwttkf3epjfkq5mynl3o3aa
764321
764320
2026-04-22T00:55:19Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM ou d'une DDR */
764321
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire.
On trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur. Elles permettent de recevoir plusieurs accès mémoire consécutifs. Si vous vous demandez comment plusieurs accès mémoire consécutifs peuvent avoir lieu, sachez que c'est une bonne question. Pour le moment, nous allons dire que ces accès proviennent du processeur ou de la mémoire cache, sans expliquer comment.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
7sjexhahos4mzv6lbis7kafzzetd8b3
764329
764321
2026-04-22T01:11:27Z
Mewtow
31375
/* Le contrôleur mémoire d'une SDRAM ou d'une DDR */
764329
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire.
On trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur. Elles permettent de recevoir plusieurs accès mémoire consécutifs. Si vous vous demandez comment plusieurs accès mémoire consécutifs peuvent avoir lieu, sachez que c'est une bonne question. Pour le moment, nous allons dire que ces accès proviennent du processeur ou de la mémoire cache, sans expliquer comment. Le contrôleur mémoire reçoit une série d'accès mémoire assez rapprochés, qu'il doit exécuter au mieux.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' détecte les succès ou défauts de page et agit en fonction. Elle ne ferme pas automatiquement la ligne ouverte, elle regarde si le prochain accès se fera dans la même ligne ou non. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant fait une commande ACT pour ouvrir la ligne suivante et une commande READ ou WRITE pour la colonne. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents. Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Maintenant, prenons le cas d'une mémoire non-utilisée, qui n'a aucun accès mémoire à traiter, aucun accès mémoire en attente. On dit que la mémoire est ''idle''. Il y a alors deux manières de gérer le tampon de ligne : soit on ferme la ligne courante dès que la mémoire passe en ''idle'', soit on attend l'accès suivant en espérant qu'il face un succès de page. La première solution tend à économiser de l'énergie, au prix d'un faible cout en performance pour les accès consécutifs. En effet, garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible.
Les contrôleurs mémoires basiques utilisent une seule des deux solutions précédentes. Soit la page est toujours fermée si la mémoire passe ''idle'', soit elle est toujours laissée ouverte. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
9pbk9hoyozx1ah2p4kn4h1nk3za9fu7
764330
764329
2026-04-22T01:14:53Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764330
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire.
On trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur. Elles permettent de recevoir plusieurs accès mémoire consécutifs. Si vous vous demandez comment plusieurs accès mémoire consécutifs peuvent avoir lieu, sachez que c'est une bonne question. Pour le moment, nous allons dire que ces accès proviennent du processeur ou de la mémoire cache, sans expliquer comment. Le contrôleur mémoire reçoit une série d'accès mémoire assez rapprochés, qu'il doit exécuter au mieux.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' ne ferme pas automatiquement la ligne. Elle la laisse ouverte, en espérant que le prochain accès mémoire se fasse dans cette ligne. Lorsqu'un nouvel accès mémoire arrive, elle doit détecter les succès ou défauts de page et agir en fonction. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant effectue les deux commandes ACT + READ ou WRITE. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. un autre défaut est que garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents.
Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Les contrôleurs mémoires basiques utilisent une des deux solutions précédentes. Soit la page est toujours fermée, soit elle est toujours laissée ouverte jusqu'à ce qu'un accès mémoire la referme. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
Il est rare qu'une SDRAM soit en état ''idle''. Cependant, rappelons qu'une SDRAM contient plusieurs banques. Concrètement, une mémoire RAM contient plusieurs sous-mémoires RAM indépendantes, reliées au même bus, qui sont regroupées dans un seul circuit imprimé. Les banques sont accessibles en parallèle, ce qui améliore grandement la performance des SDRAM. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
Un point important est qu'il n'est pas rare qu'une banque soit inutilisée pendant un temps assez long. Les optimisations précédentes peuvent s'appliquer au niveau des banques. En clair, le contrôleur mémoire peut décider de fermer des lignes ou de les laisser ouverte, banque par banque. Il peut envoyer par exemple envoyer une commande PRECHARGE pour fermer la ligne de la première banque si elle est inutilisée, mais laisser la ligne de la troisième banque ouverte.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
mws9uomnkyv4oqk9gd54bce536telu7
764331
764330
2026-04-22T01:15:41Z
Mewtow
31375
/* La politique de gestion du tampon de ligne */
764331
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire.
On trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur. Elles permettent de recevoir plusieurs accès mémoire consécutifs. Si vous vous demandez comment plusieurs accès mémoire consécutifs peuvent avoir lieu, sachez que c'est une bonne question. Pour le moment, nous allons dire que ces accès proviennent du processeur ou de la mémoire cache, sans expliquer comment. Le contrôleur mémoire reçoit une série d'accès mémoire assez rapprochés, qu'il doit exécuter au mieux.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' ne ferme pas automatiquement la ligne. Elle la laisse ouverte, en espérant que le prochain accès mémoire se fasse dans cette ligne. Lorsqu'un nouvel accès mémoire arrive, elle doit détecter les succès ou défauts de page et agir en fonction. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant effectue les deux commandes ACT + READ ou WRITE. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. un autre défaut est que garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents.
Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Les contrôleurs mémoires basiques utilisent une des deux solutions précédentes. Soit la page est toujours fermée, soit elle est toujours laissée ouverte jusqu'à ce qu'un accès mémoire la referme. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
: Le fait de laisser ouverte une ligne ou au contraire de la fermer systématiquement, se fait pour chaque banque.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
m5qe0b1i5mre5b2x21qhmox41ybmjbn
764403
764331
2026-04-22T11:23:38Z
Mewtow
31375
/* Le rafraichissement mémoire */
764403
wikitext
text/x-wiki
Les mémoires ROM ou SRAM ont généralement une interface simple, à laquelle le processeur peut s'interfacer directement. Mais pour les DRAM, ce n'est pas le cas. Les DRAM utilisent un bus d'adresse multiplexé, où l'adresse est envoyée en deux fois. Connecter le processeur directement sur une DRAM n'est pas pratique : le bus d'adresse du processeur et celui de la mémoire ne collent pas. Les DRAM doivent aussi être rafraichies régulièrement. Le rafraichissement mémoire peut être délégué au processeur, mais c'est loin d'être idéal. Et il y a bien d'autres raisons qui font que le processeur ne peut pas s'interfacer facilement avec les mémoires DRAM.
Pour gérer ces problèmes, les mémoires DRAM ne sont pas connectées directement au processeur. À la place, on ajoute un intermédiaire entre le processeur et la mémoire : le '''contrôleur mémoire externe'''. Son but est de montrer au processeur une interface simple, semblable à celle d'une SRAM classique, alors qu'il commande une mémoire DRAM à l'interface plus complexe. Il est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire.
Ce chapitre va expliquer quels sont les rôles du contrôleur mémoire, son interface et ce qu'il y a à l'intérieur. Dans ce chapitre, quand nous parlerons de ''contrôleur mémoire'', cela fera systématiquement référence au contrôleur mémoire externe. Et avant de poursuivre, sachez qu'il est difficile de faire des généralités sur les contrôleurs mémoire, car les mémoires DRAM elles-mêmes sont assez différentes les unes des autres. Entre une mémoire EDO, une mémoire SDR, une mémoire DDR et une DRAM asynchrone, les contrôleurs mémoires seront fortement différents. Aussi, il y a aura une différence entre un contrôleur pour une DRAM asynchrone et un contrôleur pour une mémoire EDO, une mémoire SDRAM, etc. J'ai choisit de vous séparer les contrôleurs mémoire pour les DRAM asynchrones de ceux pour les SDRAM/DRR.
==Le contrôleur d'une DRAM simple, asynchrone==
Les premières DRAM asynchrones avaient des contrôleurs mémoires dédiés, qui étaient séparés du processeur et du ''chipset'' de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM asynchrones qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégrés au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Leurs fonctions étaient le multiplexage de l'adresse et le rafraichissement mémoire. Ils recevaient une adresse mémoire complète, qu'ils découpaient une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre sur le bus mémoire. Pour le rafraichissement mémoire, ils rafraichissaient la DRAM régulièrement, de manière automatique, entre deux accès mémoire normaux. Le processeur n'avait ainsi plus à rafraichir la mémoire lui-même, cette fonction était déléguée au contrôleur de DRAM. Ils étaient connectés au bus d'adresse et de commande, avec éventuellement des relations indirectes avec le bus de données.
===L'interface d'un contrôleur de DRAM asynchrone===
L'interface du contrôleur mémoire décrit ses broches d'entrées/sorties et leur signification. Elle est généralement très simple et contient deux ports : un connecté au processeur, un autre connecté à la DRAM. Cela trahit d'ailleurs son rôle principal, qui est de transformer les requêtes de lecture/écriture provenant du processeur en une suite de commandes acceptée par la mémoire. Le port connecté à la DRAM est connecté ua bus d'adresse et au bus de commande. Le bus de données est lui relié au processeur et/ou au bus système.
Un accès mémoire provenant du processeur contient une adresse à lire/écrire, le bit R/W qui indique s'il faut faire une lecture ou une écriture, et éventuellement une donnée à écrire. Mais, nous avons vu que les accès mémoires sur une DRAM sont multiplexés : on envoie l'adresse en deux fois : la ligne d'abord, puis la colonne. De plus, il faut générer les signaux RAS, CAS et bien d'autres. Le tout est illustré ci-dessous.
[[File:Contrôleur mémoire.png|centre|vignette|upright=2|Contrôleur mémoire externe.]]
Pour certains contrôleurs de DRAM, il faut ajouter l''''interface électrique''', qui traduit les signaux du processeur en signaux compatibles avec la mémoire. Il est en effet très fréquent que la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit, ce qui fait qu'elles ne sont pas compatibles. Dans ce cas, le contrôleur mémoire fait la conversion.
Le contrôleur DRAM peut fonctionner en mode synchrone ou asynchrone, du point de vue du processeur. Quand il fonctionne en mode synchrone, il permet d'interfacer un processeur synchrone avec une mémoire DRAM asynchrone.
Un point important est que le contrôleur DRAM sert d'intermédiaire entre une mémoire DRAM et "le reste du monde". Il ne fait pas forcément office d'intermédiaire entre DRAM et processeur, mais peut aussi faire l'intermédiaire entre la DRAM et un bus système, entre une DRAM et le ''Video Display Controler'' d'une carte graphique, ou n'importe quel autre composant électronique qui utilise cette DRAM.
===Le générateur de ''timings'' et la traduction d'adresse===
Le contrôleur mémoire doit traduire les adresses du processeur en adresses compatibles avec la mémoire. Et la traduction est assez variable, suivant que le bus mémoire est un bus normal, un bus multiplexé, ou partiellement multiplexé. Nous avons vu ces trois types de bus mémoire dans le chapitre sur l'interface des mémoires, mais nous ferons quelques rappels rapides.
Avec un ''bus totalement multiplexé'', le bus d'adresse et le bus de données sont fusionnés. Dans ce cas, on peut envoyer soit une adresse, soit lire/écrire une donnée sur le bus, mais on ne peut pas faire les deux en même temps. Un bit ALE indique si le bus est utilisé en tant que bus d'adresse ou bus de données. Le contrôleur mémoire gère cette situation, en fixant le bit ALE et en envoyant séparément adresse et donnée pour les écritures.
[[File:Bus multiplexé avec bit ALE.png|centre|vignette|upright=2|Bus multiplexé avec bit ALE.]]
Avec un ''bus d'adresse multiplexé'', l'adresse est découpée en une adresse de ligne et une adresse de colonne, envoyées l'une après l'autre. Le contrôleur mémoire prend en entrée une adresse mémoire complète, la découpe en deux, et envoie chaque morceau au bon moment. Pour cela, il suffit d'un registre pour mémoriser l'adresse et d'un multiplexeur. Le multiplexeur choisit soit les bits de poids fort de l'adresse, soit ceux de poids faible. Les premiers correspondent à l'adresse de ligne, les autres à l'adresse de colonne.
La commande du multiplexeur est le fait d'un petit circuit séquentiel, qui génère aussi les signaux CAS et RAS. Au premier cycle, il met le signal RAS à 1, met le CAS à 0, et configure le MUX pour sélectionner les bits de poids fort. Au second cycle, il génère un signal CAS à 1, met le RAS à 0 et configure le MUX pour sélectionner les bits de poids faible. Le circuit en question est appelé le générateur de ''timings''.
[[File:Controleur de DRAM simple, sans rafraichissement mémoire.png|centre|vignette|upright=2|Contrôleur de DRAM simple, sans rafraichissement mémoire.]]
Le générateur de ''timings'' est un circuit séquentiel qui implémente une petite machine à état. Il est très simple sur une mémoire DRAM asynchrone basique, mais il est plus complexe sur les mémoires FPM, EDO, quartet, et autres. Le regroupement des multiplexeurs d'adresse et du générateur de ''timings'' est appelé le '''séquenceur mémoire'''. C'est le séquenceur mémoire qui traduit la requête processeur en commande DRAM, le reste du contrôleur est dédié au rafraichissement mémoire ou à d'autres fonctions facultatives.
===Le rafraichissement mémoire===
La gestion du rafraichissement mémoire est la fonction principale du contrôleur DRAM. Pour gérer le rafraichissement mémoire, le contrôleur mémoire intègre deux compteurs, un pour gérer l'adresse à rafraichir, l'autre pour gérer l'intervalle de temps entre deux rafraichissements.
Le rafraichissement se fait à intervalle régulier, tous les x microsecondes. Pour déclencher le rafraichissement au bon moment, le contrôleur mémoire contient un ''Refresh Timer'', aussi appelé le '''compteur de rafraichissement'''. Il est initialisé avec le temps entre deux rafraichissements, une adresse est rafraichie quand ce compteur atteint 0.
Le rafraichissement mémoire balaye la mémoire adresse par adresse. Pour savoir à quelle adresse il en est rendu, le contrôleur mémoire utilise un '''compteur d'adresse'''. Il contient la prochaine adresse à rafraichir, aussi appelée l'adresse de rafraichissement. Régulièrement, l'adresse dans ce compteur est envoyée à la RAM, pour une lecture. Mais la donnée lue n'est pas envoyée sur le bus de donnée, soit parce que la RAM est prévue pour, soit parce que le contrôleur désactive son bit ''output enable''. Dans le second cas, la RAM fait la lecture en interne, mais se déconnecte du bus de donnée, perdant la donnée lue dans le néant.
Pour envoyer l'adresse de rafraichissement sur le bus d'adresse, il faut rajouter un multiplexeur, qui choisit entre l'adresse normale et l'adresse de rafraichissement.
[[File:Controleur de DRAM avec rafraichissement mémoire.png|centre|vignette|upright=2|Controleur de DRAM avec rafraichissement mémoire.]]
Le multiplexeur ne doit cependant pas être configuré si une adresse est déjà en cours de transfert. Pour cela, un circuit d'arbitrage se débrouille pour éviter qu'un accès mémoire soit interrompu par une demande de rafraichissement et inversement. Il peut être inclus dans le séquenceur mémoire ou séparé de celui-ci.
[[File:Controleur mémoire, intérieur simplifié.png|centre|vignette|upright=2.5|Contrôleur mémoire, intérieur simplifié.]]
Il faut noter que le rafraichissement mémoire peut être délégué non pas au contrôleur mémoire, mais au processeur où à la DRAM elle-même. Quand elle est le fait du processeur, celui-ci incorpore un ''refresh timer'' et un compteur d'adresse. Un exemple est celui du processeur Zilog Z80, qui implémentait des compteurs internes pour gérer le rafraichissement mémoire. On peut considérer que le processeur incorpore alors le contrôleur mémoire, au moins partiellement. Il est aussi possible de déléguer le rafraichissement au logiciel (certains jeux vidéos Amiga ou Commodore faisaient cela pour la mémoire vidéo). Quand la DRAM elle-même s'occupe de son propre rafraichissement, c'est elle qui intègre un ''refresh timer'' et le compteur d'adresse.
===Exemple : l'Intel 8202-8203===
L'Intel 8202 et le 8203 étaient des contrôleurs de mémoire DRAM, parmi les plus simples qui soient. Ils avaient une entrée d'adresse de 12 bits, ce qui permettait d'adresser 4 kibioctets de RAM. Ils fournissaient en sortie une adresse multiplexée sur 6 bits, envoyée en deux fois. Ils avaient donc 12 entrées d'adresse, 6 sorties d'adresse, un signal RAS, un signal CAS. Les adresses présentées en entrées n'étaient pas mémorisées dans des registres, ce qui fait qu'elles devaient être maintenues durant toute la durée de l'accès mémoire. Le processeur ne pouvait donc pas se déconnecter du bus d'adresse pendant l'accès mémoire, peu importe sa durée.
Le 8202 contenait aussi un compteur de rafraichissement. Rappelons que sur les DRAM asynchrones, le rafraichissement se fait ligne par ligne. Le contrôleur mémoire a juste à présenter l'adresse de ligne, il n'a pas à envoyer l'adresse de colonne. La commande de rafraichissement se fait en mettant le signal RAS à 0, mais en laissant le CAS à 1 (je rappelle que les signaux sont actifs à 0). Le compteur d'adresse de rafraichissement a donc juste à mémoriser l'adresse de ligne. Le séquenceur mémoire était précédé par un circuit d'arbitrage, non-représenté dans le schéma ci-dessous. La microarchitecture de l'Intel 8202 est la suivante :
[[File:Microarchitecture de l'Intel 8202.png|centre|vignette|upright=2|Microarchitecture de l'Intel 8202.]]
Le 8202 avait une entrée pour un signal d'horloge, ainsi qu'un ''Chip Select'' un peu particulier. Si le signal CS passait à 0 lors d'un accès mémoire, le 8202/8203 ne se désactivait qu'une fois l'accès mémoire terminé. On ne pouvait pas l'interrompre pendant un accès mémoire, même en changeant le bit CS. Le signal d'horloge était utilisé pour commander le ''refresh timer''.
Pour commander les lectures et écriture, il recevait en entrée un bit ''Write Request'' et un bit ''Read Request'', qui demandent respectivement une écriture et une lecture. En sortie, on trouvait un unique bit R/W qui valait 0 pour une lecture et 1 pour une écriture. Il avait aussi un bit d'entrée pour forcer le rafraichissement mémoire. S'il est à 1, la mémoire rafraichie l'adresse envoyée par le processeur.
Le 8202 pouvait être connecté sur 1 à 4 chips mémoire, chacun étant appelé une '''banque'''. Cela permettait de faire passer de 4 kibioctets à 16 kibioctets de RAM maximum. Les 4 chips ne sont pas accédés en parallèle, un seul l'est à chaque fois. Pour cela, le 8202 dispose de deux bits BO et B1 pour sélectionner la banque adéquate, ainsi que 4 sorties RAS pour activer la banque adéquate. Lors du transfert d'une adresse haute, seul le signal RAS de la banque sélectionnée est activé, les autres restent à 0. Les deux bits de banque peuvent être vus comme deux bits de poids fort de l'adresse complète, sélection de la banque incluse. C'est le séquenceur mémoire qui se charge de générer ces signaux RAS, à partir des deux bits B0 et B1 (qui sont techniquement des bits d'adresse).
Pour communiquer avec le processeur, l'Intel 8202 disposait de deux bits XACK et SACK. SACK indiquait au processeur que le 8202/8203 est en train de faire un accès mémoire et qu'il est indisponible pour un second accès mémoire. Cela permet de bloquer le processeur tant que le 8202 est indisponible. Le signal XACK indique que l'accès mémoire précédent est terminé et que : soit la donnée lue est présente sur le bus de données, soit que l'écriture s'est terminée.
: Le signal SACK est très utile sur les configurations multiprocesseurs. Un processeur peut démarrer un accès mémoire, le signal SACK indiquera au second processeur qu'il doit attendre que l'accès soit terminé pour que ce soit son tour.
L'intel 8202 était un contrôleur mémoire basique. Mais Intel a vendu des contrôleurs mémoires plus complexes. Par exemple, l'Intel 8207 était un contrôleur mémoire bien plus avancé que les deux précédents. Il avait plusieurs fonctionnalités en plus du 8202/8203. Les adresses d'entrée étaient mémorisées dans des registres pour de meilleures performances. Il pouvait gérer jusqu'à 256 kibioctets de DRAM. Mais auèdelà de ça, il y avait des fonctionnalités bien plus intéressantes, à savoir : un support de l'ECC, il était double port, il permettait de simuler une DRAM synchrone à partir d'une DRAM asynchrone. Voyons comment cela était possible.
===Les contrôleurs mémoire synchrone===
Il est parfaitement possible d'utiliser un contrôleur mémoire synchrone avec une DRAM asynchrone. A vrai dire, le contrôleur DRAM peut complétement simuler une mémoire synchrone alors que la DRAM associée est asynchrone. La traduction asynchrone vers synchrone se fait en ajoutant des registres sur le bus mémoire, notamment sur le bus de données et le bus d'adresse/commande. Nous avions détaillé cela dans le chapitre sur les SRAM, c'est la même chose avec une mémoire DRAM. Sauf que cette fois-ci, le contrôleur mémoire doit aussi être prévu pour.
[[File:Controleur mémoire synchrone utilisé avec une DRAM asynchrone.png|centre|vignette|upright=2|Contrôleur mémoire synchrone utilisé avec une DRAM asynchrone]]
Les deux-trois registres illustrés plus haut peuvent être intégrés directement dans le contrôleur mémoire, que ce soit totalement ou en partie. Le strict minimum pour avoir un contrôleur mémoire synchrone est que celui-ci doit mémoriser adresse et commandes dans un registre. Par exemple, le 8207 d'Intel était capable de mémoriser les requêtes processeurs dans un registre interne, mais il fallait utiliser deux registres séparés pour le bus de données. Les deux registres étaient alors commandés par le contrôleur mémoire. Il est cependant possible d'aller plus loin et d'intégrer les registres du bus de données dans le contrôleur mémoire.
[[File:Controleur mémoire DRAM synchrone.png|centre|vignette|upright=2|Contrôleur mémoire DRAM synchrone.]]
Il faut noter que cette fonctionnalité est parfois disponible sur les SRAM. En clair, on peut associer une SRAM asynchrone avec un contrôleur de SRAM synchrone. Le contrôleur de SRAM se charge alors de simuler une SRAM synchrone à partir de la SRAM asynchrone.
===La gestion de l'ECC===
L''''ECC''' peut être géré dans le contrôleur mémoire. Pour cela, on couple les registres mentionnés dans la section précédente, avec un circuit de détection et de correction d'erreur. Le circuit d'ECC peut, comme les registres synchrones, être intégré dans le contrôleur mémoire, ou au contraire être situé dans un circuit séparé. Si le circuit d'ECC est séparé du contrôleur mémoire, il communique avec lui, histoire que le contrôleur mémoire puisse signaler toute erreur de parité ou d'ECC au processeur.
[[File:Controleur mémoire synchrone avec ECC intégré.png|centre|vignette|upright=2|Controleur mémoire synchrone avec ECC intégré]]
Reprenons l'exemple du 8207 d'Intel. Le contrôleur mémoire 8207 gère le bus d'adresse et de commande, mais n'a pas de connexions directes avec le bus de données. Il ne peut donc pas prendre en charge l'ECC. Il avait besoin d'être couplé avec un circuit d'ECC séparé, relié au bus de données : l'Intel 8206. Le 8026 prenait en entrée : 16 bits de données et 8 bits d'ECC. Il fournissait en sortie 16 bits de données après correction d'erreur, les 8 bits d'ECC pour indiquer qu'une erreur a été détectée mais pas corrigée, ainsi que des bits de parité. Le 8206 détectait/corrigeait les erreurs et générait les bits d'ECC, mais il communiquait avec le contrôleur mémoire pour cela.
[[File:8207 avec ECC.png|centre|vignette|upright=2|8207 avec ECC]]
La détection/correction d'erreur était appliquée à la fois pour les accès mémoire et pour les rafraichissements mémoire. Lors d'un rafraichissement mémoire, la donnée rafraichie est lue et réécrite. Avec l'ECC activé et configuré correctement, le rafraichissement passe par le bus de données. Au lieu d'avoir un cycle de lecture-écriture interne à la DRAM, on a un cycle de lecture-correction-écriture qui utilise le 8206. La donnée lue est envoyée sur le bus de données, puis le 8206 corrige une éventuelle erreur, et la donnée corrigée est alors réécrite en mémoire.
Au passage, si une erreur non-correctible est détectée, le 8206 ne fait rien, l'erreur est ignorée. La gestion de l'erreur sera retardée jusqu'à une lecture ultérieure. Et encore : si lecture ultérieure il y a. Si la donnée est écrasée par une écriture, la donnée corrompue sera simplement écrasée et disparaitra sans avoir pu faire le moindre dégât. Mais pour cela, le 8206 doit communiquer avec le contrôleur mémoire, pour savoir s'il est dans un cycle de rafraichissement ou un accès mémoire normal. Il prévient le 8207 lors d'une erreur, et c'est ce dernier qui décide si l'erreur doit être prise en compte ou ignorée. C'est seulement lors d'un accès mémoire normal que le processeur est prévenu qu'une erreur de parité/autre a eu lieu.
===Les contrôleurs mémoires multiports===
Les '''contrôleur mémoire multiport''' disposent de plusieurs ports, chacun permettant de traiter un accès mémoire. Ils peuvent simuler une mémoire multiport à partir d'une DRAM monoport. Évidemment, la simulation n'était pas parfaite. Des accès mémoire simultanés, envoyés en même temps sur différents ports, sont en réalité exécutés un par un, pas en même temps. Il y a donc une petite pénalité en termes de performances, mais elle est mineure.
Encore une fois, nous allons reprendre l'exemple du 8207. Il avait deux ports séparés, et était prévu pour fonctionner dans un système à deux processeurs. L'usage de deux ports séparés permettait de partager une unique mémoire DRAM entre deux processeurs. Le partage se faisait en interfaçant deux processeurs sur le contrôleur mémoire, chacun étant connecté à un port. Lors d'une lecture, il redirigeait la donnée lue vers le bon processeur, en configurant le bus de données correctement. Le contrôleur mémoire recevait des requêtes mémoire de deux processeurs, mais il les exécutait une à la fois. S'il recevait deux requêtes en même temps, l'une d'entre elles était mise en attente.
Le contrôleur mémoire doit arbitrer les accès à la mémoire, et faire en sorte que les deux processeurs aient accès à la mémoire à tour de rôle. Et non seulement il doit arbitrer les deux ports, mais il y a aussi un troisième port interne au contrôleur mémoire : le rafraichissement mémoire ! Pour cela, le circuit d'arbitrage qui choisissait entre rafraichissement mémoire et accès mémoire, est amélioré de manière à gérer un second port. Le circuit d'arbitrage donne l'accès au séquenceur mémoire à un port sélectionné. L'arbitrage était configurable, avec deux options : soit le port A est privilégié sur le port B, soit le port le plus récemment accédé à la priorité.
Les deux ports pouvaient être configurés pour fonctionner soit de manière asynchrone, soit de manière synchrone. Il était aussi possible de configurer l'ECC, des options liées à la fréquence du processeur et de la RAM, ainsi que de nombreuses options liées au rafraichissement. Pour cela, le 8207 contenait un registre de configuration interne, programmable en fournissant les entrées adéquates. Tout ce qui vient d'être dit se généralise avec plus de deux processeurs. Le 8207 ne permettait pas ça, mais les contrôleurs mémoire des PC modernes en sont capables. Ils peuvent gérer plusieurs dizaines de processeurs facilement.
==Le contrôleur mémoire d'une DRAM ''Fast Page Mode''==
Les mémoires DRAM classiques sont des mémoires à tampon de ligne, mais qui sont assez mal utilisées. Notamment, tout accès mémoire se fait en deux phases : un accès pour sélectionner la ligne, un autre pour sélectionner la colonne. Les mémoires ''Fast Page Mode'' permettent d'optimiser le tout. Elles permettent de faire plusieurs accès successifs à la même ligne, à des colonnes différentes. Et le contrôleur mémoire doit être adapté pour cela.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
===Les succès et défauts de page avec une seule banque===
Le contrôleur mémoire doit détecter que deux accès mémoire consécutifs se font dans la même ligne. Si deux accès consécutifs accèdent à la même ligne, on doit juste changer de colonne et altérer le signal CAS. C'est un ''succès de tampon de ligne'', aussi appelé un '''succès de page'''. Si deux accès consécutifs accèdent à une ligne différente, c'est un ''défaut de tampon de ligne'', aussi appelé un '''défaut de page'''. Il faut alors changer de ligne, en altérant les signaux RAS et en envoyant une adresse de ligne.
Pour détecter les succès ou défauts de page, il faut ajouter un circuit spécialisé dans le contrôleur mémoire. Il mémorise la ligne ouverte, et plus précisément son adresse de ligne (numéro de banque inclut). A chaque requête processeur, il compare l'adresse de ligne recue avec celle déjà ouverte. C'est un succès si les deux sont égales, un défaut si elles sont différentes. Le circuit qui fait cette comparaison est appelé le '''décodeur de commande'''. Il prévient le séquenceur mémoire en cas de succès de page, grâce à un signal de un bit, qui vaut 0 en cas de défaut de page et 1 en cas de succès. Le séquenceur mémoire décide alors comment gérer les signaux RAS et CAS, ainsi que l'envoi des adresses de ligne/colonne.
[[File:Controleur mémoire d'une FPM-DRAM.png|centre|vignette|upright=2|Controleur mémoire d'une FPM-DRAM]]
===Les succès et défauts de page avec une plusieurs banques===
Maintenant, qu'en est-il si le contrôleur mémoire est relié à plusieurs mémoires FPM, plusieurs banques ? Dans ce cas, il ne suffit pas de mémoriser l'adresse de ligne, il faut aussi vérifier les numéros de banque. Le séquenceur mémoire doit donc se souvenir des lignes actives dans chaque banque. Pour cela, il mémorise ces lignes dans une petite mémoire : la '''table des banques''', aussi appelée ''bank status memory''.
Pour détecter un succès ou un défaut, le contrôleur doit extraire la ligne de l'adresse, mais aussi le numéro de banque. Il envoie alors le numéro de banque à la table des banques, sur son entrée d'adresse. Il récupère alors le numéro de la ligne active sur les sorties de données. Il compare alors ce numéro de ligne avec le numéro de ligne de l'adresse envoyée par le processeur. C'est un succès si les deux sont égales, un défaut sinon.
[[File:Controleur mémoire FPM avec plusieurs banques.jpg|centre|vignette|upright=2|Contrôleur mémoire FPM avec plusieurs banques.]]
==Le contrôleur mémoire d'une SDRAM ou d'une DDR==
Comme pour les contrôleurs des DRAM asynchrones, un contrôleur de SDRAM regroupe toujours un '''séquenceur mémoire''' et une '''interface physique'''. Le séquenceur mémoire est souvent combiné avec un circuit pour le rafraichissement mémoire et un circuit d'arbitrage.
Parfois, juste avant le séquenceur mémoire, se trouve un circuit pour gérer l'entrelacement. Ce circuit intervertit certains bits de l'adresse lors des accès mémoires. Rappelons qu'avec l'entrelacement, des adresses consécutives sont placées dans des mémoires séparées, ce qui demande de jouer avec les bits d'adresse, chose qui est dévolue à l'étape de traduction d'adresse du contrôleur mémoire.
On trouve aussi des mémoires FIFOs pour mettre en attente les requêtes mémoire provenant du processeur. Elles permettent de recevoir plusieurs accès mémoire consécutifs. Si vous vous demandez comment plusieurs accès mémoire consécutifs peuvent avoir lieu, sachez que c'est une bonne question. Pour le moment, nous allons dire que ces accès proviennent du processeur ou de la mémoire cache, sans expliquer comment. Le contrôleur mémoire reçoit une série d'accès mémoire assez rapprochés, qu'il doit exécuter au mieux.
[[File:Controleur mémoire d'une SDRAM avec entrelacement.png|centre|vignette|upright=2.5|Contrôleur mémoire d'une SDRAM avec entrelacement.]]
===Les ''wait state'' et la fréquence de la SDRAM===
Les processeurs modernes sont beaucoup plus rapides que la mémoire RAM. Et ce n'est pas quelque chose qui est apparu récemment : c'était déjà un problème au temps du 486 et du premier Pentium d'Intel. Quand le processeur envoie une requête de lecture/écriture à la mémoire RAM, celle-ci met plusieurs cycles d'horloge à répondre. Et pendant ce temps, le processeur... attend. Les cycles d'horloge perdus à attendre la mémoire RAM étaient appelés des '''''Wait states'''''. De nos jours, ces ''wait state'' ont cependant disparu, grâce à de nombreuses optimisations.
La présence d'un contrôleur mémoire a permet d'éliminer les ''wait state'', dans une certaine mesure. Lors d'un ''wait state'', le processeur doit maintenir l'adresse et la donnée sur le bus mémoire pendant tout l'accès mémoire. Avec un contrôleur mémoire, le processeur envoie l'adresse, et c'est le contrôleur mémoire qui la maintient sur le bus d'adresse. Le processeur peut se déconnecter du bus mémoire et faire du travail dans son coin pendant que le contrôleur mémoire accède à la DRAM. Les ''wait state'' disparaissent alors, du moins du point de vue du processeur. Précisons cependant que si la présence d'un contrôleur mémoire n'est pas nécessaire, le processeur peut faire la même chose sans. Mais ça aide !
Contrairement aux mémoires DRAM basiques, les mémoires SDRAM sont cadencées par un signal d'horloge. Et ce signal d'horloge vient bien de quelque part. Pour cela, deux solutions : soit le contrôleur mémoire génère la fréquence qui commande la mémoire, soit il prend en entrée une fréquence de base qu'il multiplie pour obtenir la fréquence désirée. Les deux solutions sont équivalentes, si ce n'est que les circuits impliqués ne sont pas les mêmes. Dans le premier cas, le contrôleur doit embarquer un circuit oscillateur, qui génère la fréquence demandée. Dans l'autre cas, un simple multiplieur/diviseur de fréquence suffit et c'est généralement une PLL qui est utilisée pour cela.
: Notez qu'il ne faut pas confondre la fréquence de la SDRAM et celle du contrôleur mémoire. Le contrôleur mémoire fonctionne à une vitesse assez élevée, en interne. Le port relié au processeur fonctionne à haute fréquence, généralement la même que celle du processeur. A vrai dire, de nos jours, il est intégré dans le processeur.
===Le séquenceurs mémoire pour les SDRAM/DDR===
Le séquenceur mémoire existe toujours pour les mémoires SDRAM, c'est toujours un circuit séquentiel qui implémente une machine à état. Il traduit toujours une requête processeur en une séquence de commandes envoyées à des timings bien précis. Les commandes mémoires peuvent provenir de l'extérieur, mais aussi d'un circuit de rafraichissement intégré dans le contrôleur mémoire, comme pour les autres DRAM. La seule différence est que la machine à état est plus complexe.
Pour rappel, une requête de lecture/écriture se fait en trois étapes : une commande PRECHARGE pour précharger le tampon de ligne, une commande ACT qui fixe l'adresse de ligne, et enfin une commande READ/WRITE avec l'adresse de colonne. Et il faut tenir compte des timings mémoire, à savoir le fait que ces commandes sont séparées par des temps d'attentes bien précis. Par exemple, je prends des chiffres arbitraires : il faut attendre 2 cycles entre une commande ACT et une commande READ, 6 cycles avant deux commandes WRITE consécutives, etc. La gestion des ''timings'' rend la conception du séquenceur plus complexe.
Les DDR2 et 3 relaxent cependant ces contraintes avec l'optimisation des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings''. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Les SDRAM sont capables d'envoyer une commande ACT pendant que l'accès précédent envoie des données sur le bus de données (un cycle après une commande READ, par exemple). La machine à état tient compte de cette possibilité.
===La politique de gestion du tampon de ligne===
Plus haut, nous avons parlé des mémoires FPM, qui ont introduit quelques optimisations pour utiliser au mieux le tampon de ligne. Il se trouve que les SDRAM conservent ces optimisations. Il y a toujours cette notion de succès de page et de défaut de page, suivant que deux accès se font dans la même ligne ou dans deux lignes différentes. Du moins, c'est le cas si le séquenceur mémoire est coopératif. En effet, il peut fonctionner de plusieurs manières, dont les plus extrêmes sont appelés la politique de la page fermée et la politique de la page ouverte. Voyons à quoi elles correspondent.
Avec la '''politique de la page fermée''', chaque accès mémoire est suivi d'une commande PRECHARGE, qui ferme la ligne courante et précharge les lignes de bits. Même si deux accès consécutifs se font dans la même ligne, la ligne est fermée et ré-ouverte entre deux accès mémoire. En clair : l'optimisation introduite par les mémoires FPM est désactivée, le contrôleur mémoire fait exprès de ne pas en profiter. On appelle cette méthode la close ''page autoprecharge''.
Cette méthode réduit grandement les performances pour les accès à des adresses consécutives, mais fonctionne à merveille si les accès sont "aléatoires", à savoir qu'ils se font sans régularités évidentes. Son seul avantage est que l'implémentation du séquenceur mémoire est très simple. En effet, le séquenceur mémoire se passe complétement de la table des banques, du comparateur de ligne, et de tous les circuits nécessaires pour vérifier les succès ou défauts de page.
De plus, le séquenceur mémoire profite grandement des commandes READA et WRITEA, qui fusionnent une commande READ/WRITE avec une commande PRECHARGE. Le séquenceur mémoire a juste à envoyer des commandes ACT, READA, WRITEA et PREFETCH à la mémoire, pas besoin des commandes PRECHARGE, READ ou WRITE.
A l'opposé, la '''politique de la page ouverte''' ne ferme pas automatiquement la ligne. Elle la laisse ouverte, en espérant que le prochain accès mémoire se fasse dans cette ligne. Lorsqu'un nouvel accès mémoire arrive, elle doit détecter les succès ou défauts de page et agir en fonction. En cas de défaut de page, la ligne est fermée, le séquenceur mémoire envoie une commande PRECHARGE, puis l'accès suivant effectue les deux commandes ACT + READ ou WRITE. En cas de succès de page, les commandes PRECHARGE et ACT ne sont pas envoyées, seules la commande READ ou WRITE l'est.
Un désavantage est que le contrôleur mémoire doit inclure une table des banques et un comparateur, comme vu plus haut dans la section sur les mémoires FPM. un autre défaut est que garder une ligne ouverte consomme beaucoup d'énergie, comparé à un simple état de PRECHARGE. En conséquence, il est préférable de fermer les lignes dès que possible. Par contre, les performances sont d'autant meilleures que les accès mémoire consécutifs à une même ligne soient assez fréquents.
Si les accès mémoire sont aléatoires, les performances sont moins bonnes. La politique de la page fermée fermait les lignes en avance, avec des commandes READA ou WRITEA, avant même que l'accès suivant démarre. Avec la politique de la page ouverte, on doit attendre pour détecter un défaut de page, puis fermer la ligne avec une commande PRECHARGE séparée. La ligne est donc fermée avec un peu temps de retard, et envoyer deux commandes au lieu d'une prend plus de temps.
Les contrôleurs mémoires basiques utilisent une des deux solutions précédentes. Soit la page est toujours fermée, soit elle est toujours laissée ouverte jusqu'à ce qu'un accès mémoire la referme. Mais les contrôleurs plus évolués tentent de prédire s'il faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple attend un temps prédéterminé avant de fermer la ligne. Une autre solution regarde le tout dernier accès. On peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon.
Une solution plus complexe mémorise les N derniers accès et en déduit s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit. Mémoriser les N derniers accès demande d'utiliser un simple registre à décalage. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une solution simple fait la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer un petit peu l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Il existe sans doute d'autres solutions plus évoluées, mais il est difficile de savoir ce qu'il y a dans les contrôleurs de SDRAM modernes.
: Le fait de laisser ouverte une ligne ou au contraire de la fermer systématiquement, se fait pour chaque banque.
Les contrôleurs de SDRAM précédents sont assez basiques et ne représentent pas les contrôleurs les plus évolués. Ils étaient utilisés sur les anciens PC, à une époque où ils étaient encore sur la carte mère du processeur. Mais de nos jours, le contrôleur mémoire est intégré au processeur. Et il incorpore de nombreuses optimisations afin de gagner en performances. Malheureusement, ces optimisations sont elles-mêmes dépendantes des optimisations intégrées dans le processeur, ce qui fait qu'on ne peut pas en parler ici. Elles demandent que le contrôleur mémoire reçoive plusieurs accès mémoire simultanés, ce qui n'a aucun sens à ce stade du cours. Aussi, nous allons les passer sous silence pour le moment. Nous les verrons dans le chapitre sur le parallélisme mémoire.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires RAM dynamiques (DRAM)
| prevText=Les mémoires RAM dynamiques (DRAM)
| next=Les mémoires associatives
| nextText=Les mémoires associatives
}}
</noinclude>
b9for17rm0fx0b8pn8r9rfafn7hzqo7
Fonctionnement d'un ordinateur/Le parallélisme mémoire au niveau du cache
0
65888
764322
755739
2026-04-22T00:56:40Z
Mewtow
31375
/* Les MSHR intégrés au cache */
764322
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires haute performance==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
8mdb4qzz63cg7v6e89g43ufbbzb7t9p
764323
764322
2026-04-22T00:56:56Z
Mewtow
31375
/* Les contrôleurs mémoires haute performance */
764323
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Pour gagner en performances, il est possible de regarder les accès mémoire en attente, pour voir s'ils accèdent à des adresses consécutives. Le décodeur de commande sait alors quand les changements de ligne ont lieu, et donc quand envoyer des commandes PRECHARGE, voire READA et WRITEA. Mais cela demande que des accès mémoire soient en attente.
[[File:Architecture d'un module de gestion des commandes à politique dynamique.jpg|centre|vignette|upright=2.5|Architecture d'un module de gestion des commandes à politique dynamique.]]
Une autre optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
je842ugdfrj9l9wrcsdrsn9fotoxuhl
764324
764323
2026-04-22T00:58:54Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764324
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
4sao9byld78izew917tzpm8s8roo3xu
764325
764324
2026-04-22T01:01:01Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764325
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures. Cette méthode d'optimisation ne fait que fusionner des lectures consécutives ou des écritures consécutives, mais ne fait pas de ré-ordonnancement proprement dit. Une variante améliorée combine cette fusion avec du ré-ordonnancement.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
7v7occso7vx2jdis6thl6delexa2ogp
764326
764325
2026-04-22T01:01:33Z
Mewtow
31375
/* La mise en attente des accès mémoire */
764326
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire peut optimiser l'utilisation de la mémoire en changeant l'ordre des requêtes mémoires. En soi, cela peut paraitre un peu surprenant, mais nous devons faire quelques précisions. Le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée.
L'idée est alors de profiter de ce parallélisme au maximum. L'idée profite du fait que les requêtes processeurs sont mises en attente dans une mémoire FIFO. L'idée est d'utiliser une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Je dis bien : à la même adresse ! Si les accès mémoire se font à des adresses différentes, on peut faire les accès dans n'importe quel ordre. Les dépendances apparaissent quand des accès mémoire se font à une même adresse. Et là, il y a deux contraintes : deux écritures à la même adresse doivent se faire dans cet ordre, une écriture suivie d'une lecture de la même adresse doit se faire dans cet ordre.
Il suffit de regarder dans la file d'attente de chaque banque. Le principe est que le contrôleur mémoire regarde quels sont les requêtes en attente, et à quelles lignes/banques elles accèdent. Si plusieurs accès à une ligne ouverte sont présents, ils sont exécutés en priorité. Si aucun accès à la ligne ouverte n'est présent, on exécute alors l'accès mémoire le plus ancien.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
lhsm0i0y5fr9yjyzrubh15g1dqwb6rb
764327
764326
2026-04-22T01:04:27Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764327
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même ligne. L'optimisation marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
45ec2ifx8d0nl86bo2uo1lq6b3ybqdd
764328
764327
2026-04-22T01:09:51Z
Mewtow
31375
/* Le ré-ordonnancement des commandes mémoires */
764328
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même banque. L'idée est de faire en sorte que des accès consécutifs se fassent dans une même ligne. Je rappelle que les mémoires SDRAM sont des mémoires à tampon de ligne, à savoir qu'un accès mémoire se fait en deux fois. La première étape recopie une ligne de N octets dans un tampon interne à la SDRAM. La seconde étape sélectionne une colonne, à savoir une petite portion de 64 bits dans cette colonne, qui est soit envoyée sur le bus de données pour une lecture, soit modifiée par une écriture. Les deux étapes correspondent à deux commandes séparées : une commande ACT qui précise l'adresse de la ligne, et une commande READ ou WRITE qui précise l'adresse de la colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Les SDRAM permettent de se passer de la première étape si des accès consécutifs se font dans la même ligne. Une fois activée, la ligne reste ouverte et on peut accéder plusieurs fois de suite dedans. On a alors juste à préciser l'adresse de colonne dedans.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Une optimisation est alors de regrouper ensemble les accès à une même ligne. Elle marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
cgj3480jyp5eexhlitlp4maegy6fkbe
764332
764328
2026-04-22T01:23:48Z
Mewtow
31375
/* Les contrôleurs mémoires non-bloquants */
764332
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Dans ce qui suit, on part du principe qu'il y a un cache unique et une mémoire RAM, pour simplifier les explications. Mais le tout fonctionne très bien avec une hiérarchie de cache, avec quelques adaptations.
===Le tampon de remplissage de ligne===
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires SDRAM/DDR non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même banque. L'idée est de faire en sorte que des accès consécutifs se fassent dans une même ligne. Je rappelle que les mémoires SDRAM sont des mémoires à tampon de ligne, à savoir qu'un accès mémoire se fait en deux fois. La première étape recopie une ligne de N octets dans un tampon interne à la SDRAM. La seconde étape sélectionne une colonne, à savoir une petite portion de 64 bits dans cette colonne, qui est soit envoyée sur le bus de données pour une lecture, soit modifiée par une écriture. Les deux étapes correspondent à deux commandes séparées : une commande ACT qui précise l'adresse de la ligne, et une commande READ ou WRITE qui précise l'adresse de la colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Les SDRAM permettent de se passer de la première étape si des accès consécutifs se font dans la même ligne. Une fois activée, la ligne reste ouverte et on peut accéder plusieurs fois de suite dedans. On a alors juste à préciser l'adresse de colonne dedans.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Une optimisation est alors de regrouper ensemble les accès à une même ligne. Elle marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
btt7oajbiceq6pukdbaa3a9xw99a5g9
764333
764332
2026-04-22T01:25:03Z
Mewtow
31375
/* Le line fill buffer et les techniques associées */
764333
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===Le contenu du tampon de remplissage de ligne===
Le tampon de remplissage de ligne contient une ligne de cache, avec cependant quelques petits changements. On retrouve un champ pour stocker le tag, et un autre champ pour stocker la donnée chargée. Les bits de contrôle ne sont pas tous présents, vu que certains n'ont de sens que pour une ligne de cache complète. Le tampon de remplissage de ligne ne contient généralement pas de bit de validité pour toute la ligne, mais il possède quelque chose qui s'en rapproche.
Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro.
Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires SDRAM/DDR non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même banque. L'idée est de faire en sorte que des accès consécutifs se fassent dans une même ligne. Je rappelle que les mémoires SDRAM sont des mémoires à tampon de ligne, à savoir qu'un accès mémoire se fait en deux fois. La première étape recopie une ligne de N octets dans un tampon interne à la SDRAM. La seconde étape sélectionne une colonne, à savoir une petite portion de 64 bits dans cette colonne, qui est soit envoyée sur le bus de données pour une lecture, soit modifiée par une écriture. Les deux étapes correspondent à deux commandes séparées : une commande ACT qui précise l'adresse de la ligne, et une commande READ ou WRITE qui précise l'adresse de la colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Les SDRAM permettent de se passer de la première étape si des accès consécutifs se font dans la même ligne. Une fois activée, la ligne reste ouverte et on peut accéder plusieurs fois de suite dedans. On a alors juste à préciser l'adresse de colonne dedans.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Une optimisation est alors de regrouper ensemble les accès à une même ligne. Elle marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
9eqktm1csvirty3moti9chvidt0so0q
764334
764333
2026-04-22T01:27:11Z
Mewtow
31375
/* Le contenu du tampon de remplissage de ligne */
764334
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
Le tampon de remplissage de ligne contient une ligne de cache, si ce n'est que certains bits de contrôle ne sont pas présents. Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro. Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires SDRAM/DDR non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même banque. L'idée est de faire en sorte que des accès consécutifs se fassent dans une même ligne. Je rappelle que les mémoires SDRAM sont des mémoires à tampon de ligne, à savoir qu'un accès mémoire se fait en deux fois. La première étape recopie une ligne de N octets dans un tampon interne à la SDRAM. La seconde étape sélectionne une colonne, à savoir une petite portion de 64 bits dans cette colonne, qui est soit envoyée sur le bus de données pour une lecture, soit modifiée par une écriture. Les deux étapes correspondent à deux commandes séparées : une commande ACT qui précise l'adresse de la ligne, et une commande READ ou WRITE qui précise l'adresse de la colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Les SDRAM permettent de se passer de la première étape si des accès consécutifs se font dans la même ligne. Une fois activée, la ligne reste ouverte et on peut accéder plusieurs fois de suite dedans. On a alors juste à préciser l'adresse de colonne dedans.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Une optimisation est alors de regrouper ensemble les accès à une même ligne. Elle marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
e93wojpc5dhcyanqbwjzp5liqq8bzr8
764335
764334
2026-04-22T01:27:22Z
Mewtow
31375
/* Le line fill buffer et les techniques associées */
764335
wikitext
text/x-wiki
Dans ce chapitre, nous allons voir des caches qui permettent de gérer plusieurs accès mémoire simultanés directement au niveau du cache. Ils peuvent être utilisés aussi bien sur des processeurs à émission dans l'ordre que dans le désordre. Les processeurs à émission dans l'ordre ou le désordre peuvent techniquement lancer des accès mémoire à chaque cycle, mais ces accès mémoires prennent du temps, ce qui fait qu'on peut avoir des accès mémoires qui ont lieu en même temps.
Diverses techniques permettent au cache de gérer plusieurs accès simultanés. La première est l'usage de caches pipelinés, qui permet de gérer plusieurs accès mémoires en même temps. Les caches non-bloquants permettent de gérer plusieurs défauts de cache simultanés. Les deux techniques sont complémentaires, et sont parfois employées en même temps. Nous allons les voir dans ce chapitre, en commençant par les caches pipelinés.
==Le ''line fill buffer'' et les techniques associées==
Lors d'un défaut de cache, le processeur doit attendre que toute la ligne de cache soit chargée avant d'être utilisable. Or, la taille d'une ligne de cache est supérieure à la largeur du bus mémoire, ce qui fait qu'une ligne de cache est chargée en plusieurs fois, morceaux par morceaux, mot mémoire par mot mémoire. Le chargement peut se faire directement dans le cache, mais ce n'est pas une solution très pratique. À la place, beaucoup de processeurs ajoutent une mémoire tampon entre la RAM et le cache, appelée le '''tampon de remplissage de ligne''' (''line-fill buffer'') dans les processeurs modernes. Lors d'un défaut de cache, le processeur charge la donnée de la RAM dans le tampon de remplissage de ligne, mot mémoire par mot mémoire. Une fois plein, le tampon de remplissage de ligne est recopié dans la ligne de cache.
Le tampon de remplissage de ligne contient une ligne de cache, si ce n'est que certains bits de contrôle ne sont pas présents. Le tampon de remplissage de ligne contient un bit de validité pour chaque mot mémoire de la ligne de cache, qui indiquent si le mot mémoire a été chargé. Par exemple, prenons un processeur 64 bits, qui gère donc des mots mémoire de 8 octets, avec des lignes de cache 256 octets/32 mots mémoire. Le tampon de remplissage de ligne contiendra 32 bits de validité. Si le processeur a chargé les 6 premiers mots mémoire, les 6 premiers bits de validité seront mis à 1, les autres seront encore à zéro. Il faut noter que la disponibilité de la ligne complète se détermine assez facilement en faisant un ET logique entre tous les bits de validité. Le processeur sait ainsi quand la ligne de cache est disponible entièrement et donc quand la transférer dans le cache.
La même chose existe avec une hiérarchie de cache, sauf que l'on trouve une mémoire tampon entre chaque niveau de cache. Il y a un tampon de remplissage de ligne entre le cache L1 et le cache L2, entre le cache L2 et le L3, etc. Si le cache ne gère qu'un seul défaut de cache à la fois, le ''fill line buffer'' est une mémoire très simple, qui ne mémorise qu'une seule ligne de cache. Et cela vaut aussi bien pour un cache bloquant que non-bloquant. Mais sur les caches capables de gérer plusieurs défauts simultanés, le tampon de remplissage de ligne est une mémoire de type FIFO ou LIFO, capable de mémoriser plusieurs lignes de cache.
Notons que le tampon de remplissage de ligne est très utile pour implémenter certaines techniques, par exemple le contournement du cache. Nous avions vu dans le chapitre sur le cache que certains accès mémoire doivent contourner le cache, pour des raisons de cohérence des caches. C'est notamment nécessaire pour accéder aux périphériques, mais c'est aussi utile pour des raisons de performances dans des cas très spécifiques. Les accès qui contournent le cache se font directement dans le tampon de remplissage de ligne : le processeur écrit ou lit les données depuis ce tampon de remplissage de ligne, sans accéder au cache.
===L'''early restart'' et le ''critical word load''===
La présence du ''line buffer'' permet une optimisation assez intéressante, qui permet de réduire la latence des défauts de cache. L'optimisation consiste à lire un mot mémoire dans le tampon de remplissage de ligne, même si la ligne de cache complète n'a pas encore été chargée. Il existe deux manières de faire cela, qui portent les noms d'''early restart'' et de ''critical word load''. La première est la version la plus simple, la seconde est plus complexe mais plus performante.
Avec la technique d''''''early restart''''', la ligne de cache est chargée normalement, en partant de son premier mot mémoire. Dès que le mot mémoire lu/écrit par le processeur est copié dans le ''line fill buffer'', il est envoyé au processeur immédiatement. Illustrons le tout par un exemple, où une ligne de cache fait 16 mots mémoire. Le processeur effectue une lecture, qui lit le 5ème mot mémoire. Sans ''early restart'', le processeur doit charger les 16 mots mémoire avant de faire la lecture dans le cache. Avec ''early restart'', le processeur reçoit la donnée dès que le 5ème mot mémoire est disponible. Le processeur doit attendre que les 4 premiers mots mémoire soient chargés, puis le 5ème mot mémoire arrive et est envoyé directement au processeur, il est lu directement depuis le ''line fill buffer''. Les 11 mots mémoire suivants sont ensuite chargés dans le cache pendant que le processeur fait des calculs dans son coin.
Le ''critical word load'' est une optimisation de la technique précédente où le chargement de la ligne de cache commence directement à la donnée demandée par le processeur. Pour reprendre l'exemple précédent, où le processeur demande le 5ème mot mémoire sur 16, le ''critical word load'' charge le 5ème mot mémoire en premier et l'envoie au processeur, ce qui fait qu'il est chargé très rapidement. Pas besoin d'attendre que le processeur charge les 4 mots mémoire précédents comme avec l'''early restart''. Dans le détail, le processeur charge le 5ème mot mémoire en premier, puis charge les 11 suivants, et termine par les 4 mots mémoire du début. En clair, le ''critical word load'' commence par charger le mot mémoire lu, puis les blocs suivants, avant de revenir au début du bloc pour charger les blocs restants. Ainsi, la donnée demandée par le processeur sera la première disponible.
Pour cela, l'organisation du tampon de remplissage de ligne est modifiée de manière à rendre cela possible. Il a une taille égale à une ligne de cache complète, qui contient elle-même plusieurs mots mémoire. Dans le ''line-fill buffer'', chaque mot mémoire est stocké avec un tag, qui indique l'adresse du mot mémoire stocké dans le ''line-fill buffer''. Le ''line-fill buffer'' est donc un cache un peu particulier, qui fonctionne comme un cache du point de vue du processeur, comme une mémoire FIFO pour les transferts avec le cache. Ainsi, un processeur qui veut lire dans le cache après un défaut peut accéder à la donnée directement depuis le tampon de remplissage de ligne, alors que la ligne de cache n'a pas encore été totalement recopiée en mémoire.
==Les caches pipelinés==
Il est possible de pipeliner l'accès mémoire sur plusieurs cycles, avec plusieurs étages MEM consécutifs. La méthode la plus simple pipeline l'accès au cache, l'autre pipeline l'accès à la mémoire en utilisant des mémoires entrelacées. Pipeliner la mémoire est une méthode assez ancienne, utilisée sur les anciens ordinateurs historiques, qui ne disposaient pas de cache, mais avaient bien un pipeline (et parfois, de l'exécution dans le désordre et du renommage de registres). Pipeliner l'accès au cache est une technique en vigueur dans les processeurs modernes, même ceux avec un pipeline dynamique.
Beaucoup de processeurs des années 2000 avaient une fréquence peu élevée comparée aux standards d'aujourd'hui, ce qui fait que leur cache avait bien un temps d'accès d'un cycle d'horloge. Mais l'accès au cache se faisait en deux cycles d'horloge : un cycle pour calculer une adresse et un cycle pour l'accès mémoire proprement dit. Et ces deux étapes étaient pipelinées, à savoir que deux micro-opérations mémoire peuvent s'exécuter en même temps : une dans l'étage de calcul d'adresse, une autre dans le cache. L'unité mémoire était donc pipelinée, alors que l'accès au cache ne l'était pas. Les processeurs qui implémentaient cette technique regroupent les micro-architectures K5 et K6 d'AMD, les processeurs Intel de micro-architecture P6 (Pentium 2 et 3) et quelques autres.
Il est aussi possible de pipeliner l'accès au cache lui-même. Avec un cache pipeliné, l'accès au cache ne se fait pas en un seul cycle, mais en plusieurs. Cependant, on peut lancer un nouvel accès au cache à chaque cycle d'horloge, comme un processeur pipeliné lance une nouvelle instruction à chaque cycle. L'implémentation est assez simple : il suffit d'ajouter des registres dans le cache. Pour cela, on profite que le cache est composé de plusieurs composants séparés, qui échangent des données dans un ordre bien précis, d'un composant à un autre. De plus, le trajet des informations dans un cache est linéaire, ce qui les rend parfois pour l'usage d'un pipeline.
===Le ''pipelining'' des caches ''direct-mapped''===
Voici ce qui se passe avec un cache directement adressé. Pour rappel ce genre de cache est conçu en combinant une mémoire RAM, généralement une SRAM, avec quelques circuits de comparaison et un MUX. L'accès au cache se fait globalement en deux étapes : la première lit la donnée et le ''tag'' dans la SRAM, et on utilise les deux dans une seconde étape. Nous avions vu il y a quelques chapitre comment pipeliner des mémoires, dans le chapitre sur les mémoires évoluées. Et bien ces méthodes peuvent s'utiliser pour la mémoire RAM interne au cache !L'idée est d'insérer un registre entre la sortie de la RAM et la suite du cache, pour en faire un cache pipéliné, à deux étages. Le premier étage lit dans la SRAM, le second fait le reste. L'implémentation sur les caches associatifs à plusieurs voies est globalement la même à quelques détails près.
[[File:Cache directement adressé pipeliné - deux étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - deux étages]]
Avec le circuit précédent, il est possible d'aller plus loin, cette fois en pipelinant l'accès à la mémoire RAM interne au cache. Pour comprendre comment, rappelons qu'une mémoire SRAM est composée d'un plan mémoire et d'un décodeur. L'accès à la mémoire demande d'abord que le décodeur fasse son travail pour sélectionner la case mémoire adéquate, puis ensuite la lecture ou écriture a lieu dans cette case mémoire. L'accès se fait donc en deux étapes successives séparées, on a juste à mettre un registre entre les deux. Il suffit donc de mettre un gros registre entre le décodeur et le plan mémoire.
[[File:Cache directement adressé pipeliné - trois étages.png|centre|vignette|upright=2|Cache directement adressé pipeliné - trois étages]]
Et on peut aller encore plus loin en découpant le décodeur en deux circuits séparés. En effet, rappelez-vous le chapitre sur les circuits de sélection : nous avions vu qu'il est possible de créer des décodeurs en assemblant des décodeurs plus petits, contrôlés par un circuit de prédécodage. Et bien on peut encore une ajouter un registre entre ce circuit de prédécodage et les petits décodeurs.
: Théoriquement, toute l'adresse est fournie d'un seul coup au cache, la quasi-totalité des processeurs présentent l'adresse complète à un cache pipeliné. Mais le Pentium 4 fait autrement. Il faut noter que les premiers étages manipulent l'indice dans la SRAM, qui est dans les bits de poids faible, alors que les étages ultérieurs manipulent le ''tag'' qui est dans les bits de poids fort. Les concepteurs du Pentium 4 ont alors décidé de présenter les bits de poids faible lors du premier cycle d'accès au cache, puis ceux de poids fort au second cycle. Pour cela, l'ALU fonctionnait à une fréquence double de celle du processeur, tout comme le cache L1. Il n'y avait pas de pipeline proprement dit, mais cela réduisait grandement la latence d'accès au cache.
===Le ''pipelining'' des caches splittés/sériels===
Il est aussi possible de pipeliner un cache dits splittés, aussi appelés à accès sériel. Pour rappel, les caches à accès sériel vérifient si il y a succès ou défaut de cache, avant d'accéder aux lignes de cache en cas de succès. Ils font donc différemment des autres caches, qui accèdent à une ligne de cache, avant de déterminer s'il y a succès ou défaut en lisant le tag de la ligne de cache. Les caches sériels disposent de deux SRAM : une pour les tags des lignes de cache et une pour les données. Ils accèdent à la SRAM pour les tags, avant d’accéder à la SRAM des données en cas de succès de cache. Vu que l'accès se fait en deux étapes, une vérification des tags suivie de la lecture/écriture des données, il est facile à pipeliner.
Pipeliner le cache permet de régler le problème des accès au cache L1, et elle est tout le temps utilisé sur les processeurs modernes. Mais que faire en cas de défaut de cache ?
==Les caches non bloquants==
Un '''cache bloquant''' est un cache auquel le processeur ne peut pas accéder pendant un défaut de cache. Il faut attendre que la lecture ou écriture en RAM soit terminée avant de pouvoir utiliser de nouveau le cache. Un '''cache non bloquant''' n'a pas ce problème : on peut l'utiliser pendant un défaut de cache. Les caches non bloquants permettent de démarrer une nouvelle lecture ou écriture alors qu'une autre est en cours, ce qui permet d'exécuter plusieurs lectures ou écritures en même temps.
===Les ''Miss Handling Status Registers''===
Lors d'un défaut de cache, la mémoire RAM est consultée pendant le défaut de cache, mais le cache est inutilisé. Un défaut de cache n'utilise pas le cache, ce n'est qu'un accès en mémoire RAM, sur le bus mémoire (ou un accès aux niveaux de cache inférieurs, peu importe). Le cache en lui-même est laissé libre, rien n’empêche d'y accéder, il est en réalité intrinsèquement non-bloquant. Les caches, bloquants comme non-bloquants, sont en réalité composés d'une mémoire cache proprement dite, entourée de circuits qui servent d'interface entre le processeur et le cache lui-même. Et parmi les circuits tout autour, certains gèrent l'accès au cache lors d'un défaut de cache. Ils sont regroupés sous le terme de '''''Miss Handling Architecture''''' (MHA). La différence entre un cache bloquant et un cache non-bloquant est en réalité liée à l'implémentation de la MHA.
Les caches bloquants coupent volontairement l'accès au cache lors d'un défaut, car les défauts sont plus simples à gérer ainsi. Le défaut de cache rapatrie une donnée depuis la RAM, qui sera écrite dans le cache. Et il ne faut pas qu'une tentative d'accès à cette donnée ait lieu avant qu'elle ne soit chargée. Mais ce blocage est général et touche tout le cache, alors que seule une ligne de cache est concernée par le défaut de cache.
L'idée derrière un cache non-bloquant est que seule la ligne de cache est bloquée, mais les autres sont accessibles. L'idée est alors de mémoriser les lignes de cache concernées par le défaut de cache, afin d'en bloquer l'accès. À chaque accès, on vérifie si la ligne de cache est déjà réservée par un défaut de cache. La lecture/écriture est alors bloquée si c'est le cas, mais elle accepte les accès sinon. Pour cela, la ''Miss Handling Architecture'' contient des registres qui mémorisent des informations sur les défauts de cache en cours. Ils portent le nom de '''''miss status handling registers''''', que j’appellerais dorénavant MSHR, qui sont aussi appelés des '''''miss buffer'''''.
Le contenu des MSHR varie beaucoup suivant le processeur, mais ces derniers stockent au minimum les informations suivantes :
* Le numéro de la ligne de cache dans laquelle les données sont chargées.
* Un bit de validité qui indique si le MSHR est vide ou pas, qui est mis à 0 quand le défaut de cache est résolu.
* Un ou plusieurs champs de lecture/écriture, qui contiennent des informations sur la lecture/écriture.
** Pour une lecture, elle contient des informations sur la destination de la donnée, à savoir qui prévenir quand le défaut de cache est terminé. C'est parfois un nom/numéro de registre (celui dans lequel charger la donnée), mais c'est souvent le numéro de l'entrée dans le ''load/store queue''.
** Pour les écritures, elle contient la donnée à écrire, ou éventuellement un numéro de ''load/store queue'' où se trouve la donnée à écrire.
Il faut noter que le bus mémoire ne peut gérer qu'un seul défaut de cache à la fois. Aussi, il est intéressant de regarder ce qui se passe lorsqu'un second défaut de cache survient, pendant qu'un premier est en cours. Dans ce cas, il y a deux réponses qui correspondent à deux types de caches non-bloquants, qui portent les noms barbares de caches de type succès après défaut et défaut après défaut. Sur le premier type, il ne peut pas y avoir plusieurs défauts de cache simultanés. Dès qu'un second défaut de cache survient, le cache stoppe son activité et on ne peut plus démarrer de nouvelle lecture/écriture, tant que le premier défaut de cache n'est pas résolu. Le second type est plus souple et autorise la survenue de plusieurs défauts de cache simultanés. Du moins, jusqu'à une certaine limite, car le cache ne peut supporter qu'un nombre limité d'accès mémoires simultanés (pipelinés).
===Les accès simultanés à une même ligne de cache===
Il arrive que le processeur fasse plusieurs accès mémoire simultanés à la même ligne de cache. Si la ligne de cache en question n'a pas encore été chargée dans le cache, alors on a plusieurs défauts de cache consécutifs pour la même ligne de cache, et le cache non-bloquant doit gérer la situation. Pour la suite, il va falloir faire une petite distinction entre les défauts primaires et secondaires. Imaginons qu'un défaut de cache ait lieu et demande à charger une donnée dans la ligne de cache numéro N. Il s'agit du premier défaut impliquant cette ligne de cache précise, ce qui lui vaut le nom de '''défaut de cache primaire'''. Mais par la suite, d'autres accès mémoire à la même ligne de cache ont lieu, alors que la ligne de cache n'est pas encore disponible. Dans ce cas, il s'agit de '''défauts de cache secondaires'''.
Pour l'unité d'accès mémoire, les défauts de cache primaire et secondaire sont différents (ils prennent tous une entrée dans la ''load/store queue''). Mais pour le cache, ils ne correspondent qu'à un seul accès au cache : celui qui demande de charger la ligne de cache demandée. Les défauts de cache primaire et secondaire à la même ligne de cache se voient attribuer un MSHR unique. La gestion des défauts de cache secondaires dépend du cache non-bloquant. La solution la plus simple ne permet pas les défauts de cache secondaires. Le cache ne permet pas deux défauts de cache simultanés pour la même ligne de cache. Les autres solutions le permettent, en fusionnant des accès simultanés à la même ligne de cache en un seul au niveau des MSHR. Dans tous les cas, détecter les défauts de cache secondaires sont un problème qu'il faut détecter.
La ''Miss Handling Architecture'' doit détecter les défauts de cache secondaire. Pour cela, elle procède comme suit. Lors de chaque défaut de cache, la MHA récupère le numéro de la ligne de cache associé. Il vérifie alors chaque MSHR pour vérifier s'il contient le numéro en question. S'il n'y a aucune correspondance dans les MSHR, alors c'est signe que le défaut de cache est un défaut primaire. Mais s'il y en a une, alors c'est un défaut secondaire. Évidemment, cela signifie que lors d'un défaut de cache, le numéro de ligne de cache est envoyé à tous les MSHR, pour comparaison. Les MSHR sont donc regroupés dans une mémoire associative, une sorte de mini-cache, faciliter l'implémentation.
Lors d'un défaut de cache primaire, l'accès à un cache non-bloquant se fait comme suit : le processeur envoie une adresse au cache, accède à celui-ci, et détecte la survenue d'un défaut de cache. Il en profite alors pour attribuer une ligne de cache dans laquelle sera chargée ce défaut. L'attribution est très simple dans le cas des caches ''direct mapped'', ou associatifs par voie, pour lesquels l'attribution se fait assez simplement. Il mémorise alors cette information dans les MSHR, après avoir vérifié que le défaut de cache n'était pas un défaut secondaire.
Lors des accès ultérieurs à une adresse proche, censée être dans la même ligne de cache, le processeur va encore une fois rencontrer un défaut de cache. Il va alors déterminer le numéro de la ligne de cache associée à l'adresse, et comparer ce numéro avec les MSHRs. Si un MSHR contient ce numéro, c'est signe que le défaut de cache est un défaut secondaire. La MHA réagit alors différemment selon le processeur considéré. Une première solution n'autorise pas les défauts de cache secondaires. Si l'un d'entre eux survient, le processeur est gelé par un ''pipeline stall'', une bulle de pipeline. Une autre solution fusionne les défauts de cache secondaires avec le défaut de cache primaire : tout cela ne correspond qu'à un seul défaut de cache pour lui.
====Les MSHR simples====
Un cache non-bloquant à '''MSHR simple''' contient juste plusieurs MSHR qui mémorisent juste un numéro de ligne de cache, un bit de validité, le champ de lecture/écriture, et l'adresse exacte de lecture/écriture. Avec cette organisation, il est possible d'avoir plusieurs défauts de cache séparés, mais à la condition que chaque défaut accède à une ligne de cache différente. Deux accès simultanés à une même ligne de cache ne sont pas possibles, les défauts de cache secondaires ne sont pas autorisés. Ainsi, chaque défaut de cache se voit attribuer son propre MSHR, chacun contient un numéro de ligne de cache différent.
Pour comprendre pourquoi c'est impossible de gérer les défauts secondaires, il faut regarder le champ de lecture/écriture. Si on veut effectuer plusieurs écritures consécutives à la même adresse, le MSHR n'aura pas de quoi mémoriser les deux données à écrire. Il pourra mémoriser la première donnée à écrire, pas la seconde. Même chose lors d'une lecture : le champ lecture/écriture peut mémorisr la destination de la première lecture, pas de la seconde.
L'avantage est que la MHA n'a besoin que des MSHR et de quelques circuits annexes. Les autres solutions rajoutent des circuits annexes pour gérer les défauts de cache secondaires, qui utilisent beaucoup de circuits. Le cout en circuit est donc élevé, mais le gain en performance est là. Passons maintenant aux caches non-bloquants qui autorisent les défauts de cache secondaire. La solution la plus simple consiste à utiliser
====Les MSHR adressés implicitement====
Avec les '''MSHR adressés implicitement''', il est possible de fusionner plusieurs accès mémoire à une même ligne de cache, mais sous une condition très importante : ces accès lisent/écrivent des mots mémoire différents. Par exemple, imaginons qu'une ligne de cache contienne 8 mots mémoire de 64 bits. Si un premier accès mémoire lit le mot mémoire numéro 7 (dernier mot mémoire de la ligne), et le second accès le mot mémoire numéro 3, alors la fusion est possible. Mais si deux accès mémoire veulent lire/écrire le mot mémoire numéro 7, alors la fusion n'est pas possible et le processeur se bloque, un ''pipeline stall'' survient.
Un MSHR adressé implicitement est un MSHR simple, qui contient naturellement un numéro de ligne de cache (tag) et un bit de validité, sauf que le champ de lecture/écriture est dupliqué. Les différents champs lecture/écriture d'un MSHR sont regroupés dans une mémoire RAM/cache qui contient autant d'entrées qu'il y a de mot mémoire dans une ligne de cache. Chaque entrée de la table est associée à un mot mémoire de la ligne de cache et stocke des informations sur celui-ci. Une entrée mémorise, au minimum :
* Un champ de lecture/écriture qui contient soit la destination de la lecture, soit la donnée à écrire.
* Un bit R/W permettant d'interpréter correctement le champ de lecture/écriture.
* Un bit de validité pour chaque entrée de la table, qui dit si un défaut de cache antérieur accède déjà à ce mot mémoire.
La fusion de deux défauts de cache est ainsi assez simple. Un défaut de cache primaire/secondaire configure l'entrée associée au mot mémoire lu/écrit. Si un défaut secondaire ultérieur lit/écrit un mot mémoire différent (dont le bit de validité de l'entrée dans la table est à zéro), pas de conflit : il configure une autre entrée, vide. Mais s'il lit/écrit un mot mémoire pour lequel l'entrée de la table est occupée, il y a conflit, le processeur est bloqué par un ''pipeline stall'', une bulle de pipeline. Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant au nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
====Les MSHR adressés explicitement====
Les '''MSHR adressés explicitement''' n'ont pas les contraintes des MSHR adressés implicitement. Avec eux, il est possible d'avoir plusieurs défauts de cache pointant vers la même ligne de cache, mais aussi vers le même mot mémoire. De tels défauts de cache apparaissent sur les processeurs à exécution dans le désordre, mais sont très rares, voire inexistants, sur les processeurs ''in-order''.
L'idée est encore que chaque MSHR est associée à une table mémoire qui mémorise des entrées. Cette table n'est autre qu'une mémoire FIFO. Sauf que cette fois-ci, une entrée n'est pas associée à un mot mémoire. Une entrée est associée à un défaut de cache. Une entrée mémorise là encore la destination de la lecture ou la donnée de l'écriture suivi du bit R/W, ainsi que d'un bit de validité par entrée, mais aussi : la position du mot mémoire lu dans la ligne de cache. C'est cette dernière information qui n'était pas présente dans les MSHR adressés implicitement. De plus, le nombre d'entrée par MSHR n'est pas égal au nombre de mots mémoires dans une ligne de cache, mais peut être arbitrairement grand.
L'avantage d'un tel cache est qu'il est capable de traité les défauts secondaires concernant un même mot mémoire, et ce, car les accès à la ligne de cache concernée se produisent dans l'ordre de génération des défauts (la table mémoire est une FIFO).
'''Les MSHRs inversés'''
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des MSHR inversés.
Les MSHR inversés ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrées chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
====Les MSHR intégrés au cache====
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défauts de cache en attente dans cette ligne de cache.
Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défauts de cache.
==Les contrôleurs mémoires SDRAM/DDR non-bloquants==
Nous venons de voir comment une mémoire cache peut gérer plusieurs accès mémoire simultanés. Il se trouve que ce genre d'optimisation dépasse largement le cadre du cache. Les contrôleurs mémoire ne sont pas en reste, eux aussi ! les contrôleurs des mémoires DDR modernes sont capables de gérer plusieurs accès simultanés à la mémoire RAM. Pour être précis, ces accès mémoire sont mis en attente dans une mémoire FIFO, puis exécutés un par un. Le contrôleur mémoire peut intégrer des optimisations pour changer l'ordre des accès mémoire, qui plus est. Voyons cela en détail.
===La mise en attente des accès mémoire===
Comme pour les mémoires caches, il existe des contrôleurs mémoire bloquants et non-bloquants. Les premiers n'acceptent qu'un seul accès mémoire à la fois, les seconds acceptent plusieurs accès mémoire simultanés. Pour simplifier, nous allons dire que le contrôleur mémoire n’exécute qu'un seul accès mémoire à la fois, et qu'ils met en attente les accès en trop. C'est une simplification assez irréaliste, vu que les mémoires modernes disposent de plusieurs banques accessibles en parallèle. Mais nous introduirons ce détail un peu plus tard.
Avec un contrôleur mémoire de ce type, les accès mémoire sont mis en attente dans une mémoire FIFO, histoire de les exécuter dans leur ordre d'arrivée. Les accès mémoire quittent alors la mémoire dans leur ordre d'arrivée, les lectures sont renvoyées dans l'ordre demandé. En plus d'une mémoire FIFO pour les commandes mémoire, on trouve une mémoire FIFO pour les données à écrire. Elle permet d'accumuler plusieurs écritures, tout en permettant que la donnée adéquate soit envoyée à la RAM au bon moment. Il y a aussi une FIFO pour les données lues, qui sert au cas où le cache ne soit pas disponible quand on lui envoie la donnée lue.
[[File:Module d'interface avec la mémoire.png|centre|vignette|upright=2.5|Contrôleur mémoire avec mise en attente des requêtes processeur et autres optimisations.]]
Une optimisation regroupe plusieurs accès à des données consécutives en un seul accès en rafale. Le contrôleur mémoire analyse les requêtes mises en attente et détecte si certaines se font à des adresses consécutives. Si c'est le cas, il fusionne ces requêtes en une lecture/écriture en rafale. Une telle optimisation est appelée la '''combinaison de lecture''' pour les lectures, et la '''combinaison d'écriture''' pour les écritures.
===Le ré-ordonnancement des commandes mémoires===
Le contrôleur mémoire précédent est très simple, mais il ne correspond à ce qu'on trouve dans un contrôleur mémoire moderne. Un contrôleur mémoire moderne n'utilise pas une mémoire FIFO pour mettre en attente les lectures et écritures. Il préfère changer l'ordre des requêtes mémoires, pour gagner en performances.
Il faut préciser que le contrôleur mémoire ne remet pas les accès mémoire dans l'ordre avant de les envoyer au processeur. A la place, il reçoit des requêtes mémoire qui sont "numérotées", qui ont identifiant pour les identifier. Le contrôleur mémoire exécute les lectures/écritures dans le désordre, mais garde la trace de leur identifiant. Pour les lectures, il renvoie la donnée lue avec l'identifiant. Le processeur sait alors à quelle lecture la donnée lue correspond et il se débrouille en interne pour gérer la situation. En clair : le processeur voit les accès mémoire dans le désordre, c'est lui qui les remet en ordre.
L'implémentation la plus basique n'a rien de vraiment compliqué. Pour rappel, une SDRAM contient plusieurs banques indépendantes, qu'on peut accéder en parallèle. Il est possible de lancer un accès mémoire dans deux banques en même temps, par exemple. Ou encore, on peut lancer un nouvel accès mémoire dans une banque si elle est inoccupée. L'implémentation la plus basique utilise une mémoire FIFO par banque. Ainsi, les accès dans une même banque se feront en série, dans l'ordre d'arrivée, mais des accès à des banques différentes se feront dans le désordre. Cela ne pose pas de problème car les accès se font à des adresses différentes, ce qui fait qu'il n'y a pas de conflits majeurs.
[[File:Gestion parallèle des banques.png|centre|vignette|upright=2.5|Gestion parallèle des banques.]]
Le ré-ordonnancement peut aussi regrouper les accès dans une même banque. L'idée est de faire en sorte que des accès consécutifs se fassent dans une même ligne. Je rappelle que les mémoires SDRAM sont des mémoires à tampon de ligne, à savoir qu'un accès mémoire se fait en deux fois. La première étape recopie une ligne de N octets dans un tampon interne à la SDRAM. La seconde étape sélectionne une colonne, à savoir une petite portion de 64 bits dans cette colonne, qui est soit envoyée sur le bus de données pour une lecture, soit modifiée par une écriture. Les deux étapes correspondent à deux commandes séparées : une commande ACT qui précise l'adresse de la ligne, et une commande READ ou WRITE qui précise l'adresse de la colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Les SDRAM permettent de se passer de la première étape si des accès consécutifs se font dans la même ligne. Une fois activée, la ligne reste ouverte et on peut accéder plusieurs fois de suite dedans. On a alors juste à préciser l'adresse de colonne dedans.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Une optimisation est alors de regrouper ensemble les accès à une même ligne. Elle marche si plusieurs accès à une même ligne ne sont pas consécutifs, et qu'il y a des accès entre les deux. Après ré-ordonnancement, ces accès mémoire deviennent consécutifs, ils sont exécutés l'un à la suite de l'autre. Cela permet de profiter au mieux de la politique à page ouverte. L'idée est de profiter du fait qu'une page est restée ouverte pour effectuer un maximum d'accès dans cette ligne avant de la fermer.
Pour rendre le tout plus concret, voici un exemple. Imaginez que l'on sait les 3 accès mémoire suivants :
* Une lecture ligne A ;
* Une écriture ligne B ;
* Une lecture ligne A.
Sans réordonnancent, on doit émettre deux commandes PRECHARGE : une quand on passe de la ligne A à la ligne B, et une autre pour le passage inverse. pour éviter cela, le contrôleur mémoire peut retarder l'écriture, ou au contraire avancer la seconde lecture. le résultat est alors le suivant :
* Lecture ligne A ;
* Lecture ligne A ;
* Une écriture ligne B.
On a donc deux accès consécutifs à la même ligne, suivi par une écriture dans une autre ligne. La technique marche parce que l'on a un mix adéquat de lectures et d'écritures. Mais il existe des possibilités de réorganisation autres qui ne sont pas valides. Il faut par exemple prendre garde à éviter d'intervertir lectures et écritures à une même adresse, sous peine de problèmes. Encore une fois, il faut faire attention aux dépendances mémoires. Le controleur mémoire teste les dépendances mémoires avant d'envoyer des commandes à la mémoire DDR/SDRAM.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=La désambiguïsation mémoire
| prevText=La désambiguïsation mémoire
| next=Les processeurs superscalaires
| nextText=Les processeurs superscalaires
}}
</noinclude>
sp1icgqdux4hh39jngvtpgdmkwn4j2q
Fonctionnement d'un ordinateur/Les mémoires RAM dynamiques (DRAM)
0
71327
764265
733923
2026-04-21T20:08:20Z
Mewtow
31375
/* Les mémoires SDRAM */
764265
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives. Ces lectures ou écritures accèderont à la même ligne, mais à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR.
Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
3k6fqno72pq2dl6x7cu4evyt5ta052p
764284
764265
2026-04-21T21:23:27Z
Mewtow
31375
/* Les commandes SDRAM */
764284
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives. Ces lectures ou écritures accèderont à la même ligne, mais à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR.
Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
rsa8kol29t4oja9nitj46s620nyfw9v
764286
764284
2026-04-21T21:33:43Z
Mewtow
31375
/* Les commandes SDRAM */
764286
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR.
Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
py4jnbs71vdpbzwtslxgvk9frpkm2g6
764288
764286
2026-04-21T21:40:09Z
Mewtow
31375
/* Les commandes des mémoires DDR */
764288
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR.
Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
o4w86dh9k86n103x51tpe43x8y6f0v5
764297
764288
2026-04-21T22:12:04Z
Mewtow
31375
/* Les mémoires DDR */
764297
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
9pbjrfagalfi04cguc1clsy6z5zobz2
764298
764297
2026-04-21T22:17:59Z
Mewtow
31375
/* Les mémoires SDRAM */
764298
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
Sur la quasi-totalité des DRAM, modernes comme anciennes, le rafraichissement est géré par le processeur ou le contrôleur mémoire. Le rafraichissement est déclenché par une commande de rafraichissement, provenant du processeur ou du contrôleur mémoire. Une commande de rafraichissement est un troisième type d'accès mémoire, séparé de la lecture ou de l'écriture, qui n’existe que sur les DRAM de ce type.
Une commande de rafraichissement ordonne de rafraichir une adresse, parfois une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
d8wfxiqcg0w6k4nqefo19ux1iv27dqb
764336
764298
2026-04-22T01:30:51Z
Mewtow
31375
/* Les DRAM à rafraichissement externe et pseudo-statiques */
764336
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
==Le rafraichissement mémoire==
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
===Les DRAM à rafraichissement externe et pseudo-statiques===
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
===L'impact du rafraichissement sur les performances===
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
5s3psue0usjhtpl1sd5kvuogxj8963j
764337
764336
2026-04-22T01:31:09Z
Mewtow
31375
/* Le rafraichissement mémoire */
764337
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
Le rafraichissement mémoire a un impact sur les performances. L'envoi des commandes de rafraichissement entre des lectures/écritures fait qu'une partie du débit binaire de la mémoire est gâché. De même, ces commandes doivent être envoyées à des timings bien précis, et peuvent entrer en conflit avec des lectures ou écritures simultanées.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Le rafraichissement étalé est étalé dans le temps, ce qui permet des accès mémoire entre chaque rafraichissement de ligne/adresse. Les PC gagnent en performance avec le rafraichissement étalé. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
e1stfis2pirh048vm2n870jcgli036g
764338
764337
2026-04-22T01:33:07Z
Mewtow
31375
/* Le rafraichissement mémoire */
764338
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Dans le premier cas, le rafraichissement se fait adresse par adresse, on doit préciser l'adresse à chaque fois. Le second cas est spécifique aux mémoires à tampon de ligne, organisées en lignes et colonnes. La lecture d'une ligne la rafraichit automatiquement, ce qui fait qu'il suffit de d'adresser une ligne, pas besoin de préciser la colonne. Les commandes sont donc plus courtes.
Enfin, un dernier cas permet d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour cela, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
gmwdddjoe3eswqw3548ad2lmybadf4c
764339
764338
2026-04-22T01:34:46Z
Mewtow
31375
/* Le rafraichissement mémoire */
764339
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
La mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire.
Le contrôleur mémoire est reliée au CPU par un bus, et est connecté aux barrettes ou boitiers de DRAM via le bus mémoire proprement dit. Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur mémoire, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
mfazdtkpin5z39ggzemjdoc69dlnbcm
764340
764339
2026-04-22T01:37:32Z
Mewtow
31375
764340
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. La raison à cela est que l'interface d'une mémoire DRAM est un peu compliquée, elle est différente de l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur mémoire, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple.
Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM. Par exemple, les contrôleurs mémoires des toutes premières DRAM ne géraient pas du tout le rafraichissement mémoire, qui était géré par le processeur. Par exemple, le processeur Zilog Z80 implémentait des compteurs pour gérer le rafraichissement mémoire. D'autres processeurs avaient des interruptions dédiées pour gérer le rafraichissement mémoire. Mais les contrôleurs mémoires modernes gèrent le rafraichissement mémoire de manière automatique.
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
rqs7yndue4do0ptp75d0s7vuyv36na8
764402
764340
2026-04-22T11:22:49Z
Mewtow
31375
/* Le contrôleur mémoire externe */
764402
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
Un point important est que les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Le contrôleur mémoire sert d'intermédiaire, d'interface entre la DRAM et le processeur. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. La raison à cela est que l'interface d'une mémoire DRAM est un peu compliquée, elle est différente de l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur mémoire est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur mémoire, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur mémoire ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur mémoire externe===
Le contrôleur mémoire gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur mémoire varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurs mémoire étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les composants Intel 8202, Intel 8203 et Intel 8207 étaient des contrôleurs mémoire pour DRAM qui étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur mémoire avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur mémoire DRAM d'une manière ou d'une autre. Notons que le contrôleur mémoire est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
5f1y0oul6megyyf4lddx721zomjptfc
764404
764402
2026-04-22T11:27:44Z
Mewtow
31375
/* L'interface des DRAM et le contrôleur mémoire */
764404
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurS de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur mémoire liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur mémoire ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur mémoire externe. Et ce contrôleur mémoire est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur mémoire peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur mémoire peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur mémoire.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
rnkg56f6gj96bg4zm6erv2rlw6w8m6q
764405
764404
2026-04-22T11:29:22Z
Mewtow
31375
764405
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurS de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur de DRAM liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur de DRAM ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur de DRAM. Et ce contrôleur de DRAM est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur de DRAM peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur de DRAM peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur de DRAM.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
b8xt617uehp9ncvb0rjqbyi64pxfmsu
764406
764405
2026-04-22T11:29:46Z
Mewtow
31375
/* Le contrôleur de DRAM */
764406
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurs de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse. Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur de DRAM liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur de DRAM ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur de DRAM. Et ce contrôleur de DRAM est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur de DRAM peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur de DRAM peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur de DRAM.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
7te9gu2xvbgy4hhe2quvupbgb2xmilf
764407
764406
2026-04-22T11:54:21Z
Mewtow
31375
/* Les mémoires FPM */
764407
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurs de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse.
Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité de pipelining limitée aux mémoires FPM. L'implémentation n'est pas différente des mémoires FPM, si ce n'est qu'il y a un registre ajouté sur la sortie de donnée pour les lectures, un peu comme sur les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur de DRAM liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur de DRAM ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur de DRAM. Et ce contrôleur de DRAM est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur de DRAM peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur de DRAM peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur de DRAM.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
2sjq2yhlvhmowg9mymai8enbgpc67op
764408
764407
2026-04-22T11:55:58Z
Mewtow
31375
/* Les mémoires EDO-RAM */
764408
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurs de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse.
Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité dite de ''pipelining'', en ajoutant un registre sur la sortie de donnée pour les lectures, sur le même modèle que pour les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur de DRAM liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur de DRAM ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur de DRAM. Et ce contrôleur de DRAM est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
===Les banques et ''ranks''===
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur de DRAM peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur de DRAM peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur de DRAM.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
qjqyvfz8ydh4m34kcoqe89dg8szzclo
764409
764408
2026-04-22T11:56:40Z
Mewtow
31375
/* Les mémoires SDRAM */
764409
wikitext
text/x-wiki
Les mémoires RAM dynamiques sont opposées aux mémoires RAM statiques. Les RAM statiques sont les plus intuitives à comprendre : elles conservent leurs données tant qu'on ne les modifient pas, ou tant que l’alimentation électrique est maintenue. Les RAM dynamiques ont pour défaut que les données s'effacent après un certain temps, en quelques millièmes ou centièmes de secondes si l'on n'y touche pas. En conséquence, il faut réécrire chaque bit de la mémoire régulièrement pour éviter qu'il ne s'efface. On dit qu'on doit effectuer régulièrement un '''rafraîchissement mémoire'''.
Le rafraîchissement prend du temps, et a tendance à légèrement diminuer la rapidité des mémoires dynamiques. Mais en contrepartie, les mémoires dynamiques ont une meilleure capacité, car leurs bits prennent moins de place, utilisent moins de transistors. Et c'est ce qui explique que la mémoire principale de l'ordinateur, la fameuse mémoire RAM, est actuellement une mémoire dynamique sur tous les PC actuels. Dans ce chapitre, nous allons voir comment fonctionnent les mémoires RAM dynamiques, aussi appelées mémoires DRAM.
==L'interface des DRAM et le contrôleur mémoire==
L'interface d'une mémoire DRAM est plus compliquée que l'interface d'une SRAM basique. Et c'est suffisant pour qu'on ait besoin d'un intermédiaire pour faire la conversion entre processeur et DRAM. Les DRAM modernes ne sont pas connectées directement au processeur, mais le sont par l'intermédiaire d'un '''contrôleur mémoire externe'''. Il ne faut pas le confondre avec le contrôleur mémoire interne, placé dans la mémoire RAM, et qui contient notamment le décodeur. Les deux sont totalement différents, bien que leur nom soit similaire. Pour éviter toute confusion, j'utiliserais le terme de '''contrôleur de DRAM''', plus parlant.
===Le bus d'adresse des DRAM est multiplexé===
Un point important pour le contrôleur de DRAM est de transformer les adresses mémoires fournies par le processeur, en adresses utilisables par la DRAM. Car les DRAM ont une interface assez spécifique. Les DRAM ont ce qui s'appelle un '''bus d'adresse multiplexé'''. Avec de tels bus, l'adresse est envoyée en deux fois. Les bits de poids fort sont envoyés avant les bits de poids faible. On peut ainsi envoyer une adresse de 32 bits sur un bus d'adresse de 16 bits, par exemple. Le bus d'adresse contient alors environ moitié moins de fils que la normale.
Pour rappel, l'avantage de cette méthode est qu'elle permet de limiter le nombre de fils du bus d'adresse, ce qui très intéressant sur les mémoires de grande capacité. Les mémoires DRAM étant utilisées comme mémoire principale d'un ordinateur, elles devaient avoir une grande capacité. Cependant, avoir un petit nombre de broches sur les barrettes de mémoire est clairement important, ce qui impose d'utiliser des stratagèmes. Envoyer l'adresse en deux fois répond parfaitement à ce problème : cela permet d'avoir des adresses larges et donc des mémoires de forte capacité, avec une performance acceptable et peu de fils sur le bus d'adresse.
Les bus multiplexés se marient bien avec le fait que les DRAM sont des mémoires à adressage par coïncidence ou à tampon de ligne. Sur ces mémoires, l'adresse est découpée en deux : une adresse haute pour sélectionner la ligne, et une adresse basse qui sélectionne la colonne. L'adresse est envoyée en deux fois : la ligne, puis la colonne. Pour savoir si une donnée envoyée sur le bus d'adresse est une adresse de ligne ou de colonne, le bus de commande de ces mémoires contenait deux fils bien particuliers : les RAS et le CAS. Pour simplifier, le signal RAS permettait de sélectionner une ligne, et le signal CAS permettait de sélectionner une colonne.
[[File:Signaux RAS et CAS.png|centre|vignette|upright=2|Signaux RAS et CAS.]]
Si on a deux bits RAS et CAS, c'est parce que la mémoire prend en compte les signaux RAS et CAS quand ils passent de 1 à 0. C'est à ce moment là que la ligne ou colonne dont l'adresse est sur le bus sera sélectionnée. Tant que des signaux sont à zéro, la ligne ou colonne reste sélectionnée : on peut changer l'adresse sur le bus, cela ne désélectionnera pas la ligne ou la colonne et la valeur présente lors du front descendant est conservée.
[[File:L'intérieur d'une FPM.png|centre|vignette|upright=2|L'intérieur d'une FPM.]]
===Le rafraichissement mémoire===
La spécificité des DRAM est qu'elles doivent être rafraichies régulièrement, sans quoi leurs cellules perdent leurs données. Le rafraichissement est basiquement une lecture camouflée. Elle lit les cellules mémoires, mais n'envoie pas le contenu lu sur le bus de données. Rappelons que la lecture sur une DRAM est destructive, à savoir qu'elle vide la cellule mémoire, mais que le système d'amplification de lecture régénère le contenu de la cellule automatiquement. La cellule est donc rafraichie automatiquement lors d'une lecture.
La quasi-totalité des DRAM supporte des commandes de rafraichissement, séparées des lectures et écritures classiques. Une commande de rafraichissement ordonne de rafraichir une adresse, voire une ligne complète. Les commandes de rafraichissement sont générées par le contrôleur de DRAM, dans la grosse majorité des cas. Il est aussi possible que ce soit le processeur qui les génère, mais c'est beaucoup plus rare.
Il est aussi possible d'envoyer des commandes de rafraichissement vides, qui ne précisent ni adresse ni numéro de ligne. Pour les gérer, la mémoire contient un compteur, qui pointe sur la prochaine ligne à rafraichir, qui est incrémenté à chaque commande de rafraichissement. Une commande de rafraichissement indique à la mémoire d'utiliser l'adresse dans ce compteur pour savoir quelle adresse/ligne rafraichir.
[[File:Rafraichissement mémoire automatique.png|centre|vignette|upright=2|Rafraichissement mémoire automatique.]]
Il existe des mémoires qui sont des intermédiaires entre les mémoires SRAM et DRAM. Il s'agit des '''mémoires pseudo-statiques''', qui sont techniquement des mémoires DRAM, utilisant des transistors et des condensateurs, mais qui gèrent leur rafraichissement mémoire toutes seules. Le rafraichissement mémoire est alors totalement automatique, ni le processeur, ni le contrôleur de DRAM ne devant s'en charger. Le rafraichissement est purement le fait des circuits de la mémoire RAM et devient une simple opération de maintenance interne, gérée par la RAM elle-même.
L'envoi des commandes de rafraichissement peuvent se faire de deux manières : soit on les envoie toutes en même temps, soit on les disperse le plus possible. Le premier cas est un '''rafraichissement en rafale''', le second un '''rafraichissement étalé'''. Le rafraichissement en rafale n'est pas utilisé dans les PC, car il bloque la mémoire pendant un temps assez long. Mais les anciennes consoles de jeu gagnaient parfois à utiliser eu rafraichissement en rafale. En effet, la mémoire était souvent effacée entre l'affichage de deux images, pour éviter certains problèmes dont on ne parlera pas ici. Le rafraichissement de la mémoire était effectué à ce moment là : l'effacement rafraichissait la mémoire.
Le temps mis pour rafraichir la mémoire est le temps mis pour parcourir toute la mémoire. Il s'agit du temps de balayage vu dans le chapitre sur les performances d'un ordinateur. Concrètement, il est défini en divisant la capacité de la mémoire par son débit binaire. C'est le temps nécessaire pour lire ou réécrire tout le contenu de la mémoire. Cependant, il faut signaler que l'usage de banques mémoire change la donne. Il est en effet possible de rafraichir des banques indépendantes en même temps, ce qui divise le temps de rafraichissement par le nombre de banques.
===Le contrôleur de DRAM===
Le contrôleur de DRAM gère le bus mémoire et tout ce qui est envoyé dessus. Il envoie des commandes aux barrettes de mémoire, commandes qui peuvent être des lectures, des écritures, ou des demandes de rafraichissement, parfois d'autres commandes. La mémoire répond à ces commandes par l'action adéquate : lire la donnée et la placer sur le bus de données pour une commande de lecture, par exemple. Le rôle du contrôleur de DRAM varie grandement suivant le contrôleur en question, ainsi que selon le type de DRAM.
Les anciens contrôleurs de DRAM étaient des composants séparés du processeur, du ''chipset'' ou du reste de la carte mère. Par exemple, les contrôleur de DRAM Intel 8202, Intel 8203 et Intel 8207 étaient vendus dans des boitiers DIP et étaient soudés sur la carte mère. Par la suite, ils ont été intégré au ''chipset'' de la carte mère pendant les décennies 90-2000. Après les années 2000, ils ont été intégrés dans les processeurs.
Il est possible de connecter plusieurs barrettes sur le même bus mémoire, ou alors celles-ci sont connectées au contrôleur de DRAM avec un bus par barrette/boitier. C'est ce qui permet de placer plusieurs barrettes de mémoire sur la même carte mère : toutes les barrettes sont connectées au contrôleur de DRAM d'une manière ou d'une autre. Notons que le contrôleur de DRAM est presque toujours un circuit synchrone, cadencé par une horloge, comme le processeur. Et ce peu importe que les mémoires DRAM soient elles-mêmes synchrones ou au contraire asynchrones (sans horloge).
==Les mémoires asynchrones à RAS/CAS : FPM et EDO-RAM==
Avant l'invention des mémoires SDRAM et DDR, il exista un grand nombre de mémoires différentes, les plus connues étant les mémoires fast page mode et EDO-RAM. Ces mémoires n'étaient pas synchronisées par un signal d'horloge, c'était des '''mémoires asynchrones'''. Quand ces mémoires ont été créées, cela ne posait aucun problème : les accès mémoire étaient très rapides et le processeur était certain que la mémoire aurait déjà fini sa lecture ou écriture au cycle suivant. Les mémoires asynchrones les plus connues étaient les '''mémoires FPM''' et '''mémoires EDO'''.
===Les mémoires FPM===
Les '''mémoires FPM (''Fast Page Mode'')''' possédaient une petite amélioration, qui rendait l'adressage plus simple. Avec elles, il n'y a pas besoin de préciser deux fois la ligne si celle-ci ne changeait pas lors de deux accès consécutifs : on pouvait garder la ligne sélectionnée durant plusieurs accès. Par contre, il faut quand même préciser les adresses de colonnes à chaque changement d'adresse.
Il existe une petite différence entre les mémoire FPM proprement dit et les mémoires ''Fast-Page Mode''. Sur les premières, le signal CAS est censé passer à 0 avant qu'on fournisse l'adresse de colonne. Avec les ''Fast-Page Mode'', l'adresse de colonne pouvait être fournie avant que l'on configure le signal CAS. Cela faisait gagner un petit peu de temps, en réduisant quelque peu le temps d'accès total.
[[File:Sélection d'une ligne sur une mémoire FPM ou EDO.png|centre|vignette|upright=2|Sélection d'une ligne sur une mémoire FPM ou EDO.]]
Avec les '''mémoires en mode quartet''', il est possible de lire quatre octets consécutifs sans avoir à préciser la ligne ou la colonne à chaque accès. On envoie l'adresse de ligne et l'adresse de colonne pour le premier accès, mais les accès suivants sont fait automatiquement. La seule contrainte est que l'on doit générer un front descendant sur le signal CAS pour passer à l'adresse suivante. Vous aurez noté la ressemblance avec le mode rafale vu il y a quelques chapitres, mais il y a une différence notable : le mode rafale vrai n'aurait pas besoin qu'on précise quand passer à l'adresse suivante avec le signal CAS.
[[File:Mode quartet.png|centre|vignette|upright=3|Mode quartet.]]
Les '''mémoires FPM à colonne statique''' se passent même du signal CAS. Le changement de l'adresse de colonne est détecté automatiquement par la mémoire et suffit pour passer à la colonne suivante. Dans ces conditions, un délai supplémentaire a fait son apparition : le temps minimum entre deux sélections de deux colonnes différentes, appelé tCAS-to-CAS.
[[File:Accès en colonne statique.jpg|centre|vignette|upright=2.5|Accès en colonne statique.]]
===Les mémoires EDO-RAM===
L''''EDO-RAM''' a été inventée quelques années après la mémoire FPM. Elle a été déclinée en deux versions : la EDO simple, et la EDO en rafale.
L''''EDO simple''' ajoutait une capacité dite de ''pipelining'', en ajoutant un registre sur la sortie de donnée pour les lectures, sur le même modèle que pour les mémoires SRAM synchrones. La donnée pouvait être maintenue sur le bus de données durant un certain temps, même après la remontée du signal CAS. Le registre de sortie maintenait la donnée lu tant que le signal RAS restait à 0, et tant qu'un nouveau signal CAS n'a pas été envoyé. Faire remonter le signal CAS à 1 n'invalidait pas la donnée en sortie.
La conséquence est qu'on pouvait démarrer un nouvel accès alors que la donnée de l'accès précédent était encore présent sur le bus de données. Le pipeline obtenu avait deux étages : un où on présentait l'adresse et sélectionnait la colonne, un autre où la donnée était lue depuis le registre de sortie. Les mémoires EDO étaient donc plus rapides.
[[File:EDO RAM.png|centre|vignette|upright=3|EDO RAM]]
Les '''EDO en rafale''' effectuent les accès à 4 octets consécutifs automatiquement : il suffit d'adresser le premier octet à lire. Les 4 octets étaient envoyés sur le bus les uns après les autres, au rythme d'un par cycle d’horloge : ce genre d'accès mémoire s'appelle un accès en rafale.
[[File:Accès en rafale.png|centre|vignette|upright=2|Accès en rafale sur une DRAM EDO.]]
Implémenter cette technique nécessite d'ajouter un compteur, capable de faire passer d'une colonne à une autre quand on lui demande, et quelques circuits annexes pour commander le tout.
[[File:Modifications du contrôleur mémoire liées aux accès en rafale.png|centre|vignette|upright=2|Modifications du contrôleur de DRAM liées aux accès en rafale.]]
===Le rafraichissement mémoire===
Les mémoires FPM et EDO doivent être rafraichies régulièrement. Au début, le rafraichissement se faisait ligne par ligne. Le rafraichissement avait lieu quand le RAS passait à l'état haut, alors que le CAS restait à l'état bas. Le processeur, ou le contrôleur mémoire, sélectionnait la ligne à rafraichir en fournissant son adresse mémoire. D'où le nom de '''rafraichissement par adresse''' qui est donné à cette méthode de commande du rafraichissement mémoire.
Divers processeurs implémentaient de quoi faciliter le rafraichissement par adresse. Par exemple, le Zilog Z80 contenait un compteur de ligne, un registre qui contenait le numéro de la prochaine ligne à rafraichir. Il était incrémenté à chaque rafraichissement mémoire, automatiquement, par le processeur lui-même. Un ''timer'' interne permettait de savoir quand rafraichir la mémoire : quand ce ''timer'' atteignait 0, une commande de rafraichissement était envoyée à la mémoire, et le ''timer'' était ''reset''.
[[File:Rafraichissement mémoire manuel.png|centre|vignette|upright=2|Rafraichissement mémoire manuel.]]
Par la suite, certaines mémoires ont implémenté un compteur interne d'adresse, pour déterminer la prochaine adresse à rafraichir sans la préciser sur le bus d'adresse. Le déclenchement du rafraichissement se faisait toujours par une commande externe, provenant du contrôleur de DRAM ou du processeur. Cette commande faisait passer le CAS à 0 avant le RAS. Cette méthode de rafraichissement se nomme '''rafraichissement interne'''.
[[File:Rafraichissement sur CAS précoce.png|centre|vignette|upright=2|Rafraichissement sur CAS précoce.]]
On peut noter qu'il est possible de déclencher plusieurs rafraichissements à la suite en laissant le signal CAS dans le même état. Ce genre de choses pouvait avoir lieu après une lecture : on pouvait profiter du fait que le CAS soit mis à zéro par la lecture ou l'écriture pour ensuite effectuer des rafraichissements en touchant au signal RAS. Dans cette situation, la donnée lue était maintenue sur la sortie durant les différents rafraichissements.
[[File:Rafraichissements multiples sur CAS précoce.png|centre|vignette|upright=2|Rafraichissements multiples sur CAS précoce.]]
==Les mémoires SDRAM==
Dans les années 90, les mémoires asynchrones ont laissé la place aux '''mémoires SDRAM''', qui sont synchronisées avec le bus par une horloge. L'utilisation d'une horloge a comme avantage des temps d'accès fixes : le processeur sait qu'un accès mémoire prendra un nombre déterminé de cycles d'horloge et peut faire ce qu'il veut dans son coin durant ce temps. Avec les mémoires asynchrones, le processeur ne pouvait pas prévoir quand la donnée serait disponible et ne faisait rien tant que la mémoire n'avait pas répondu : il exécutait ce qu'on appelle des ''wait states'' en attendant que la mémoire ait fini.
Les mémoires SDRAM sont standardisées par un organisme international, le JEDEC. Le standard SDRAM impose des spécifications électriques bien précise pour les barrettes de mémoire et le bus mémoire, décrit le protocole utilisé pour communiquer avec les barrettes de mémoire, et bien d'autres choses encore. Le standard autorise l'utilisation de 2 à 8 banques dans chaque barrette de SDRAM, autorise une forme de pipeline (une commande peut démarrer avant que la précédente termine), les barrettes mémoires utilisent de l'entrelacement. Les SDRAM ont été déclinées en versions de performances différentes, décrites dans le tableau ci-dessous :
{| class="wikitable"
! Nom standard
! Fréquence
! Bande passante
|-
| PC66
| 66 mhz
| 528 Mio/s
|-
| PC66
| 100 mhz
| 800 Mio/s
|-
| PC66
| 133 mhz
| 1064 Mio/s
|-
| PC66
| 150 mhz
| 1200 Mio/s
|}
Une mémoire SDRAM contient plusieurs banques séparées, accessibles en parallèle. Il s'agit d'une propriété qui améliore grandement leurs performances. Il est en effet possible de faire plusieurs accès mémoire en parallèle, dans des banques différentes. Il est par exemple possible de lancer un accès mémoire dans une banque, alors qu'un accès est en cours dans une autre banque. La possibilité est limitée, mais elle existe.
===Le mode rafale===
Les SDRAM gèrent à la fois l'accès entrelacé et l'accès linéaire. Nous avions vu ces deux types d'accès dans le chapitre sur les mémoires évoluées, mais faisons un bref rappel. Le mode linéaire est le mode rafale normal : un compteur est incrémenté à chaque cycle et son contenu est additionné à l'adresse de départ. Le mode entrelacé utilise un ordre différent. Avec ce mode de rafale, le contrôleur mémoire effectue un XOR bit à bit entre un compteur (incrémenté à chaque accès) et l'adresse de départ pour calculer la prochaine adresse de la rafale.
Sur les SDRAM, les paramètres qui ont trait au mode rafale sont modifiables, programmables. Déjà, on peut configurer la mémoire pour effectuer au choix des accès sans rafale ou des accès en rafale. Ensuite, on peut décider s'il faut faire un accès en mode linéaire ou entrelacé. Il y a aussi la possibilité de configurer le nombre d'octets consécutifs à lire ou écrire en mode rafale. On peut ainsi accéder à 1, 2, 4, ou 8 octets en une seule fois, alors que les EDO ne permettaient que des accès à 4 octets consécutifs.
===Les délais mémoires===
Il faut un certain temps pour sélectionner une ligne ou une colonne, sans compter qu'une SDRAM doit gérer d'autres temps d'attente plus ou moins bien connus : ces temps d'attente sont appelés des délais mémoires. La façon de mesurer ces délais varie : sur les mémoires FPM et EDO, on les mesure en unités de temps (secondes, millisecondes, micro-secondes, etc.), tandis qu'on les mesure en cycles d'horloge sur les mémoires SDRAM.
{|class="wikitable"
|-
!Timing!!Description
|-
||tRAS||Temps mis pour sélectionner une ligne.
|-
||tCAS||Temps mis pour sélectionner une colonne.
|-
||tRP||Temps mis pour réinitialiser le tampon de ligne et décharger la ligne.
|-
||tRCD||Temps entre la fin de la sélection d'une ligne, et le moment où l'on peut commencer à sélectionner la colonne.
|-
||tWTR||Temps entre une lecture et une écriture consécutives.
|-
||tCAS-to-CAS||Temps minimum entre deux sélections de deux colonnes différentes.
|}
Les délais/timings mémoire ne sont pas les mêmes suivant la barrette de mémoire que vous achetez. Certaines mémoires sont ainsi conçues pour avoir des timings assez bas et sont donc plus rapides, et surtout : beaucoup plus chères que les autres. Le gain en performances dépend beaucoup du processeur utilisé et est assez minime comparé au prix de ces barrettes. Les circuits de notre ordinateur chargés de communiquer avec la mémoire (ceux placés soit sur la carte mère, soit dans le processeur), doivent connaitre ces timings et ne pas se tromper : sans ça, l’ordinateur ne fonctionne pas.
===Le registre de mode du contrôleur mémoire===
Les mémoires SDRAM sont connectées à un bus mémoire spécifique, qui lui-même est commandé par un contrôleur de DRAM. Et ce contrôleur de DRAM est partiellement configurable pour les SDRAM. La configuration en question permet de gérer diverses options du mode rafale, comme le tableau ci-dessous le montre bien.
Le contrôleur mémoire interne de la SDRAM mémorise ces informations dans un registre de 10 bits, le '''registre de mode'''. Il contient un bit qui permet de préciser s'il faut effectuer des accès normaux ou des accès en rafale, ainsi qu'un autre bit pour configurer le type de rafale (normale, entrelacée). Il mémorise aussi le nombre d'octets consécutifs à lire ou écrire. Voici à quoi correspondent les 10 bits de ce registre :
{|class="wikitable"
|+ Signification des bits du registre de mode des SDRAM
|-
! Bit n°9
| Type d'accès : en rafale ou normal
|-
! Bit n°8 et 7
| Doivent valoir 00, sont réservés pour une utilisation ultérieur dans de futurs standards.
|-
! Bit n°6, 5, et 4
| Latence CAS
|-
! Bit n°3
| Type de rafale : linéaire ou entrelacée
|-
! Bit n°2, 3, et 0
| Longueur de la rafale : indique le nombre d'octets à lire/écrire lors d'une rafale.
|}
===Les commandes SDRAM===
Le bus de commandes d'une SDRAM contient évidemment un signal d'horloge, pour cadencer la mémoire, mais pas que. En tout, 18 fils permettent d'envoyer des commandes à la mémoire, commandes qui vont effectuer une lecture, une écriture, ou autre chose dans le genre. Les commandes en question sont des demandes de lecture, d'écriture, de préchargement et autres. Elles sont codées par une valeur bien précise qui est envoyée sur les 18 fils du bus de commande. Ces commandes sont nommées READ, READA, WRITE, WRITEA, PRECHARGE, ACT, ...
{| class="wikitable" style="text-align:center"
! Bit CS || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lit une donnée depuis la ligne active.
|-
| 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lit une donnée depuis la ligne active, puis ferme la ligne.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrit une donnée dans la ligne active.
|-
| 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrit une donnée dans la ligne active, puis ferme la ligne.
|-
| 0 || 0 || 1 || 1 || Adresse de la banque || colspan="2" | Adresse de la ligne || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne dans toutes les banques.
|-
| 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
Les commandes READ et WRITE ne peuvent se faire qu'une fois que la banque a été activée par une commande ACT. Une fois la banque et la ligne activée par une commande ACT, il est possible d'envoyer plusieurs commandes READ ou WRITE successives à des colonnes différentes. Le commandes ACT se font à partir de l'état de repos, l'état où toutes les banques sont préchargées. Par contre, les commandes MODE REGISTER SET et AUTO REFRESH ne peuvent se faire que si toutes les banques sont désactivées.
La commande PRECHARGE ferme la ligne courante et prépare l'ouverture de la suivante. Elle précharge les lignes de bit de la RAM, d'où son nom. Il est nécessaire d'en envoyer une avant d'envoyer une commande ACT. Les commandes READA et WRITEA fusionnent une commande READ/WRITE avec une commande PRECHARGE. Elles permettent d'éviter d'avoir à envoyer une commande PRECHARGE pour fermer la ligne courante. Au lieu d'envoyer une commande READ ou WRITE, puis une commande PRECHARGE pour fermer la ligne, on envoie une seule commande READA/WRITEA. Il s'agit d'une petite optimisation, qui permet de réduire le nombre de commandes envoyées sur le bus.
Le fonctionnement simplifié d'une SDRAM peut se résumer dans ce diagramme :
[[File:Fonctionnement simplifié d'une SDRAM.jpg|centre|vignette|upright=2|Fonctionnement simplifié d'une SDRAM.]]
==Les mémoires DDR==
Les mémoires SDRAM récentes sont des mémoires de type ''dual data rate'', ce qui fait qu'elles portent le nom de mémoires DDR. Pour rappel, les mémoires ''dual data rate'' ont un plan mémoire deux fois plus large que le bus mémoire, avec un bus mémoire allant à une fréquence double. Par double, on veut dire que les transferts sur le bus mémoire ont lieu sur les fronts montants et descendants de l'horloge. Il y a donc deux transferts de données sur le bus pour chaque cycle d'horloge, ce qui permet de doubler le débit sans toucher à la fréquence du plan mémoire lui-même.
Les mémoires DDR sont standardisées par un organisme international, le JEDEC, et ont été déclinées en plusieurs générations : DDR1, DDR2, DDR3, et DDR4. La différence entre ces modèles sont très nombreuses, mais les plus évidentes sont la fréquence de la mémoire et du bus mémoire. D'autres différences mineures existent entre les SDRAM et les mémoires DDR. Par exemple, la tension d'alimentation des mémoires DDR est plus faible que pour les SDRAM. ET elle a diminué dans le temps, d'une génération de DDR à l'autre. Avec les mémoires DDR2,la tension d'alimentation est passée de 2,5/2,6 Volts à 1,8 Volts. Avec les mémoires DDR3, la tension d'alimentation est notamment passée à 1,5 Volts.
===Les performances des mémoires DDR===
Les mémoires SDRAM ont évolué dans le temps, mais leur temps d'accès/fréquence n'a pas beaucoup changé. Il valait environ 10 nanosecondes pour les SDRAM, approximativement 5 ns pour la DDR-400, il a peu évolué pendant la génération DDR et DDR3, avant d'augmenter pendant les générations DDR4 et de stagner à nouveau pour la génération DDR5. L'usage du DDR, puis du QDR, visait à augmenter les performances malgré la stagnation des temps d'accès. En conséquence, la fréquence du bus a augmenté plus vite que celle des puces mémoire pour compenser.
{|class="wikitable"
|-
! Année
! Type de mémoire
! Fréquence de la mémoire (haut de gamme)
! Fréquence du bus
! Coefficient multiplicateur entre les deux fréquences
|-
| 1998
| DDR 1
| 100 - 200 MHz
| 200 - 400 MHz
| 2
|-
| 2003
| DDR 2
| 100 - 266 MHz
| 400 - 1066 MHz
| 4
|-
| 2007
| DDR 3
| 100 - 266 MHz
| 800 - 2133 MHz
| 8
|-
| 2014
| DDR 4
| 200 - 400 MHz
| 1600 - 3200 MHz
| 8
|-
| 2020
| DDR 5
| 200 - 450 MHz
| 3200 - 7200 MHz
| 8 à 16
|}
Une conséquence est que la latence CAS, exprimée en nombre de cycles, a augmenté avec le temps. Si vous comparez des mémoires DDR2 avec une DDR4, par exemple, vous allez voir que la latence CAS est plus élevée pour la DDR4. Mais c'est parce que la latence est exprimée en nombre de cycles d'horloge, et que la fréquence a augmentée. En comparant les temps d'accès exprimés en secondes, on voit une amélioration.
===Les commandes des mémoires DDR===
Les commandes des mémoires DDR sont globalement les mêmes que celles des mémoires SDRAM, vues plus haut. Les modifications entre SDRAM, DDR1, DDR2, DDR3, DDR4, et DDR5 sont assez mineures. Les seules différences sont l'addition de bits pour la transmission des adresses, des bits en plus pour la sélection des banques, un registre de mode un peu plus grand (13 bits sur la DDR 2, au lieu de 10 sur les SDRAM). En clair, une simple augmentation quantitative.
Avant la DDR4, les modifications des commandes sont mineures. La DDR2 supprime la commande ''Burst Terminate'', la DDR3 et la DDR4 utilisent le bit A12 pour préciser s'il faut faire une rafale complète, ou une rafale de moitié moins de données. Une optimisation des DDR2 et 3 est celle des '''CAS postés'''. L'idée est que le contrôleur de DRAM peut envoyer une commande ACT et une commande READ/WRITE sans se soucier des ''timings'' nécessaires entre les deux. En théorie, les deux commandes doivent être séparées par quelques cycles, sur une SDRAM ou une DDR1. Mais avec la DDR2, le contrôleur de DRAM peut envoyer les deux l'une après l'autre, au cycle suivant. C'est la mémoire qui mettra en attente la commande READ/WRITE pour respecter les ''timings'' mémoire. Cela complexifie le fonctionnement interne de la DDR, mais simplifie grandement le travail du contrôleur de DRAM.
Mais avec la DDR4, les choses changent, notamment au niveau de la commande ACT. Avec l'augmentation de la capacité des barrettes mémoires, la taille des adresses est devenue trop importante. Il a donc fallu rajouter des bits d'adresses. Mais pour éviter d'avoir à rajouter des broches sur des barrettes déjà bien fournies, les concepteurs du standard DDR4 ont décidé de ruser. Lors d'une commande ACT, les bits RAS, CAS et WE sont utilisés comme bits d'adresse, alors qu'ils ont leur signification normale pour les autres commandes. Pour éviter toute confusion, un nouveau bit ACT est ajouté pour indiquer la présence d'une commande ACT : il est à 1 pour une commande ACT, 0 pour les autres commandes.
{| class="wikitable" style="text-align:center"
|+ Commandes d'une mémoire DDR4, seule la commande colorée change par rapport aux SDRAM
! Bit CS || style="background: #CCFFCC" | Bit ACT || Bit RAS || Bit CAS || Bit WE || Bits de sélection de banque (2 bits) || Bit du bas d'adresse A10 || Reste du bus d'adresse || Nom de la commande : Description
|-
| 1
| colspan="6" | X
| Absence de commandes.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 1 || colspan="3" | X || No Operation : Pas d'opération
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 1 || 0 || colspan="3" | X || Burst Terminante : Arrêt d'un accès en rafale en cours.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 0 || Adresse de la colonne || READ : lire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 1 || Adresse de la banque || 1 || Adresse de la colonne || READA : lire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 0 || Adresse de la colonne || WRITE : écrire une donnée depuis la ligne active.
|-
| 0 || style="background: #CCFFCC" | 0 || 1 || 0 || 0 || Adresse de la banque || 1 || Adresse de la colonne || WRITEA : écrire une donnée depuis la ligne active, avec rafraichissement automatique de la ligne.
|- style="background: #CCFFCC"
| 0 || style="background: #CCFFCC" | 1 || colspan="3" | Adresse de la ligne (bits de poids forts) || Adresse de la banque || colspan="2" | Adresse de la ligne (bits de poids faible) || ACT : charge une ligne dans le tampon de ligne.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la banque || 0 || X || PRECHARGE : précharge le tampon de ligne dans la banque voulue.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 1 || 0 || Adresse de la X || 1 || X || PRECHARGE ALL : précharge le tampon de ligne' dans toutes les banques.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 1 || colspan="3" | X || Auto refresh : Demande de rafraichissement, gérée par la SDRAM.
|-
| 0 || style="background: #CCFFCC" | 0 || 0 || 0 || 0 || 00 || colspan="2" | Nouveau contenu du registre de mode || LOAD MODE REGISTER : configure le registre de mode.
|}
==Les VRAM des cartes vidéo==
Les cartes graphiques ont des besoins légèrement différents des DRAM des processeurs, ce qui fait qu'il existe des mémoires DRAM qui leur sont dédiées. Elles sont appelés des '''''Graphics RAM''''' (GRAM). La plupart incorporent des fonctionnalités utiles uniquement pour les mémoires vidéos, comme des fonctionnalités de masquage (appliquer un masque aux données lue ou à écrire), ou le remplissage d'un bloc de mémoire avec une donnée unique.
Les anciennes cartes graphiques et les anciennes consoles utilisaient de la DRAM normale, faute de mieux. La première GRAM utilisée était la NEC μPD481850, qui a été utilisée sur la console de jeu PlayStation, à partir de son modèle SCPH-5000. D'autres modèles de GRAM ont rapidement suivi. Les anciennes consoles de jeu, mais aussi des cartes graphiquesn utilisaient des GRAM spécifiques.
===Les mémoires vidéo double port===
Sur les premières consoles de jeu et les premières cartes graphiques, le ''framebuffer'' était mémorisé dans une mémoire vidéo spécialisée appelée une '''mémoire vidéo double port'''. Le premier port était connecté au processeur ou à la carte graphique, alors que le second port était connecté à un écran CRT. Aussi, nous appellerons ces deux port le ''port CPU/GPU'' et l'autre sera appelé le ''port CRT''. Le premier port était utilisé pour enregistrer l'image à calculer et faire les calculs, alors que le second port était utilisé pour envoyer à l'écran l'image à afficher. Le port CPU/GPU est tout ce qu'il y a de plus normal : on peut lire ou écrire des données, en précisant l'adresse mémoire de la donnée, rien de compliqué. Le port CRT est assez original : il permet d'envoyer un paquet de données bit par bit.
De telles mémoires étaient des mémoires à tampon de ligne, dont le support de mémorisation était organisé en ligne et colonnes. Une ligne à l'intérieur de la mémoire correspond à une ligne de pixel à l'écran, ce qui se marie bien avec le fait que les anciens écrans CRT affichaient les images ligne par ligne. L'envoi d'une ligne à l'écran se fait bit par bit, sur un câble assez simple comme un câble VGA ou autre. Le second port permettait de faire cela automatiquement, en permettant de lire une ligne bit par bit, les bits étant envoyés l'un après l'autre automatiquement.
Pour cela, les mémoires vidéo double port incorporaient un tampon de ligne spécialisé pour le port lié à l'écran. Ce tampon de ligne n'était autre qu'un registre à décalage, contrairement au tampon de ligne normal. Lors de l'accès au second port, la carte graphique fournissait un numéro de ligne et la ligne était chargée dans le tampon de ligne associé à l'écran. La carte graphique envoyait un signal d'horloge de même fréquence que l'écran, qui commandait le tampon de ligne à décalage : un bit sortait à chaque cycle d'écran et les bits étaient envoyé dans le bon ordre.
===Les mémoires SGRAM et GDDR===
De nos jours, les cartes graphiques n'utilisent plus de mémoires double port, mais des mémoires simple port. Les mémoires graphiques actuelles sont des SDRAM modifiées pour fonctionner en tant que ''Graphic RAM''. Les plus connues sont les '''mémoires GDDR''', pour ''graphics double data rate'', utilisées presque exclusivement sur les cartes graphiques. Il en existe plusieurs types pendant que j'écris ce tutoriel : GDDR, GDDR2, GDDR3, GDDR4, et GDDR5. Mais attention, il y a des différences avec les DDR normales. Par exemple, les GDDR ont une fréquence plus élevée que les DDR normales, avec des temps d'accès plus élevés (sauf pour le tCAS). De plus, elles sont capables de laisser ouvertes deux lignes en même temps. Par contre, ce sont des mémoires simple port.
==Les mémoires SLDRAM, RDRAM et associées==
Les mémoires précédentes sont généralement associées à des bus larges. Les mémoires SDRAM et DDR modernes ont des bus de données de 64 bits de large, avec des d'adresse et de commande de largeur similaire. Le nombre de fils du bus mémoire dépasse facilement la centaine de fils, avec autant de broches sur les barrettes de mémoire. Largeur de ces bus pose de problèmes problèmes électriques, dont la résolution n'est pas triviale. En conséquence, la fréquence du bus mémoire est généralement moins performantes comparé à ce qu'on aurait avec un bus moins large.
Mais d'autres mémoires DRAM ont exploré une solution alternative : avoir un bus peu large mais de haute fréquence, sur lequel on envoie les commandes/données en plusieurs fois. Elles sont regroupées sous le nom de '''DRAM à commutation par paquets'''. Elles utilisent des bus spéciaux, où les commandes/adresses/données sont transmises par paquets, par trames, en plusieurs fois. En théorie, ce qu'on a dit sur le codage des trames dans le chapitre sur le bus devrait s'appliquer à de telles mémoires. En pratique, les protocoles de transmission sur le bus mémoire sont simplifiés, pour gérer le fonctionnement à haute fréquence. Le processeur envoie des paquets de commandes, les mémoires répondent avec des paquets de données ou des accusés de réception.
Les mémoires à commutation par paquets sont peu nombreuses. Les plus connues sont les mémoires conçues par la société Rambus, à savoir la ''RDRAM'' (''Rambus DRAM'') et ses deux successeurs ''XDR RAM'' et ''XDR RAM 2''. La ''Synchronous-link DRAM'' (''SLDRAM'') est un format concurrent conçu par un consortium de plusieurs concepteurs de mémoire.
===La SLDRAM (''Synchronous-link DRAM'')===
Les '''mémoires SLDRAM''' avaient un bus de données de 64 bits allant à 200-400 Hz, avec technologie DDR, ce qui était dans la norme de l'époque pour la fréquence (début des années 2000). Elle utilisait un bus de commande de 11 bits, qui était utilisé pour transmettre des commandes de 40 bits, transmises en quatre cycles d'horloge consécutifs (en réalité, quatre fronts d'horloge donc deux cycles en DDR). Le bus de données était de 18 bits, mais les transferts de donnée se faisaient par paquets de 4 à 8 octets (32-65 bits). Pour résumer, données et commandes sont chacunes transmises en plusieurs cycles consécutifs, sur un bus de commande/données plus court que les données/commandes elle-mêmes.
Là où les SDRAM sélectionnent la bonne barrette grâce à des signaux de commande dédiés, ce n'est pas le cas avec la SLDRAM. A la place, chaque barrette de mémoire reçoit un identifiant, un numéro codé sur 7-8 bits. Les commandes de lecture/écriture précisent l'identifiant dans la commande. Toutes les barrettes reçoivent la commande, elles vérifient si l'identifiant de la commande est le leur, et elles la prennent en compte seulement si c'est le cas.
Voici le format d'une commande SLDRAM. Elle contient l'adresse, qui regroupe le numéro de banque, le numéro de ligne et le numéro de colonne. On trouve aussi un code commande qui indique s'il faut faire une lecture ou une écriture, et qui configure l'accès mémoire. Il configure notamment le mode rafale, en indiquant s'il faut lire/écrire 4 ou 8 octets. Enfin, il indique s'il faut fermer la ligne accédée une fois l'accès terminé, ou s'il faut la laisser ouverte. Le code commande peut aussi préciser que la commande est un rafraichissement ou non, effectuer des opérations de configuration, etc. L'identifiant de barrette mémoire est envoyé en premier, histoire que les barrettes sachent précocement si l'accès les concerne ou non.
{|class="wikitable" style="text-align:center"
|+SLDRAM Read, write or row op request packet
! FLAG || CA9 || CA8 || CA7 || CA6 || CA5 || CA4 || CA3 || CA2 || CA1 || CA0
|-
! 1
| colspan=9 bgcolor=#ffcccc| Identifiant de barrette mémoire|| bgcolor=#ccffcc| Code de commande
|-
! 0
| colspan=5 bgcolor=#ccffcc| Code de commande ||colspan=3 bgcolor=#ff88ff| Banque||colspan=2 bgcolor=#ffffcc| Ligne
|-
! 0
| colspan=9 bgcolor=#ffffcc| Ligne || 0
|-
! 0
| 0 || 0 || 0 ||colspan=7 bgcolor=#ccffff| Colonne
|}
===Les mémoires Rambus===
Les mémoires conçues par la société Rambus regroupent la '''RDRAM''' (''Rambus DRAM'') et ses deux successeurs '''XDR RAM''' et '''XDR RAM 2'''.
Les toutes premières étaient les '''mémoires RDRAM''', où le bus permettait de transmettre soit des commandes (adresse inclue), soit des données, avec un multiplexage total. Le processeur envoie un paquet contenant commandes et adresse à la mémoire, qui répond avec un paquet d'acquittement. Lors d'une lecture, le paquet d'acquittement contient la donnée lue. Lors d'une écriture, le paquet d'acquittement est réduit au strict minimum. Le bus de commandes est réduit au strict minimum, à savoir l'horloge et quelques bits absolument essentiels, les bits RW est transmis dans un paquet et n'ont pas de ligne dédiée, pareil pour le bit OE. Toutes les barrettes de mémoire doivent vérifier toutes les transmissions et déterminer si elles sont concernées en analysant l'adresse transmise dans la trame.
Elles ont été utilisées dans des PC ou d'anciennes consoles de jeu. Par exemple, la Nintendo 64 incorporait 4 mébioctets de mémoire RDRAM en tant que mémoire principale. La RDRAM de la Nintendo 64 était cadencée à 500 MHz, utilisait un bus de 9 bits, et avait un débit binaire maximal théorique de 500 MB/s. La Playstation 2 contenait quant à elle 32 mébioctets de RDRAM en ''dual-channel'', pour un débit binaire de 3.2 Gibioctets par seconde. Les processeurs Pentium 3 pouvaient être associés à de la RDRAM sur certaines mères. Les Pentium 4 étaient eux aussi associés à la de RDRAM, mais les cartes mères ne géraient que ce genre de mémoire. La Playstation 3 contenait quant à elle de la XDR RAM.
==Les barrettes de mémoire DRAM==
[[File:Ram-module.svg|droite|vignette|upright=0.5|Barrette de mémoire RAM.]]
Dans les PC, les mémoires prennent la forme de '''barrettes mémoires'''. Les barrettes de mémoire se fixent à la carte mère sur un connecteur standardisé, appelé '''slot mémoire'''. Le dessin ci-contre montre une barrette de mémoire, celui-ci ci-dessous est celui d'un ''slot'' mémoire.
[[File:Dual channel slots.jpg|centre|vignette|Slots mémoires.]]
===Le format des barrettes de mémoire===
Sur le schéma de droite, on remarque facilement les boitiers de DRAM, rectangulaires, de couleur sombre. Chaque barrette combine ces puces de manière à additionner leurs capacités : on peut ainsi créer une mémoire de 8 gibioctets à partir de 8 puces d'un gibioctet, par exemple. Ils sont soudés sur un PCB en plastique vert sur lequel sont gravés des connexions métalliques. Certaines barrettes ont des puces mémoire d'un seul côté alors que d'autres en ont sur les deux faces. Cela permet de distinguer les barrettes SIMM et DIMM.
* Les '''barrettes SIMM''' ont des puces sur une seule face de la barrette. Elles étaient utilisées pour les mémoires FPM et EDO-RAM.
* Les '''barrettes DIMM''' ont des puces sur les deux côtés. Elles sont utilisées sur les SDRAM et les DDR.
{| class="flexible"
|+ '''Barrette SIMM'''
|-
|[[File:SIMM FPM 4 MB - C0448721-7229.jpg|vignette|SIMM recto.]]
|[[File:SIMM FPM 4 MB - C0448721-7230.jpg|vignette|SIMM verso.]]
|}
Les trucs dorés situés en bas des barrettes de mémoire sont des broches qui connectent la barrette au bus mémoire. Les barrettes des mémoires FPM/EDO/SDRAM/DDR n'ont pas le même nombre de broches, pour des raisons de compatibilité.
{|class="wikitable"
|-
!Type de barrette
!Type de mémoire
!Nombre de broches
|-
| rowspan="2" | SIMM
| rowspan="2" | FPM/EDO
|30
|-
|72
|-
| rowspan="4" | DIMM
|SDRAM
|168
|-
|DDR
|184
|-
|DDR2
|214, 240 ou 244, suivant la barrette ou la carte mère.
|-
|DDR3
|204 ou 240, suivant la barrette ou la carte mère.
|}
Enfin, les barrettes n'ont pas le même format, car il n'y a pas beaucoup de place à l'intérieur d'un PC portable, ce qui demande de diminuer la taille des barrettes. Les barrettes '''SO-DIMM''', pour ordinateurs portables, sont différentes des barrettes DIMM normales des DDR/SDRAM.
{|
|-
|[[File:Desktop DDR Memory Comparison.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC de bureau.]]
|[[File:Laptop SODIMM DDR Memory Comparison V2.svg|centre|vignette|upright=1.5|Barrettes de DDR pour PC portables.]]
|}
Les barrettes de Rambus ont parfois été appelées des '''barrettes RB-DIMM''', mais ce sont en réalité des DIMM comme les autres. La différence principale est que la position des broches n'était pas la même que celle des formats DIMM normaux, sans compter que le connecteur Rambus n'était pas compatible avec les connecteurs SDR/DDR normaux.
===Les interconnexions à l'intérieur d'une barrette de mémoire===
Les boîtiers de DRAM noirs sont connectés au bus par le biais de connexions métalliques. Toutes les puces sont connectées aux bus d'adresse et de commande, ce qui permet d'envoyer la même adresse/commande à toutes les puces en même temps. La manière dont ces puces sont reliées au bus de commande dépend selon la mémoire utilisée.
Les DDR1 et 2 utilisent ce qu'on appelle une '''topologie en T''', illustrée ci-dessous. On voit que le bus de commande forme une sorte d'arbre, dont chaque extrémité est connectée à une puce. La topologie en T permet d'égaliser le délai de transmission des commandes à travers le bus : la commande transmise arrive en même temps sur toutes les puces. Mais elle a de nombreux défauts, à savoir qu'elle fonctionne mal à haute fréquence et qu'elle est aussi difficile à router parce que les nombreuses connexions posent problèmes.
[[File:Organisation des bus de commandes sur les DDR1-2.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR1-2, nommée topologie en T.]]
En comparaison, les DDR3 utilisent une '''topologie ''fly-by''''', où les puces sont connectées en série sur le bus de commande/adresse. La topologie ''fly-by'' n'a pas les problèmes de la topologie en T : elle est simple à router et fonctionne très bien à haute fréquence.
[[File:Organisation des bus de commandes sur les DDR3 - topologie fly-by.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les DDR3 - topologie ''fly-by'']]
===Les barrettes tamponnées (à registres)===
Certaines barrettes intègrent un registre tampon, qui fait l'interface entre le bus et la barrette de RAM. L'utilité est d'améliorer la transmission du signal sur le bus mémoire. Sans ce registre, les signaux électriques doivent traverser le bus, puis traverser les connexions à l'intérieur de la barrette, jusqu'aux puces de mémoire. Avec un registre tampon, les signaux traversent le bus, sont mémorisés dans le registre et c'est tout. Le registre envoie les commandes/données jusqu'aux puces mémoire, mais le signal a été régénéré par le registre. Le signal transmis est donc de meilleure qualité, ce qui augmente la fiabilité du système mémoire. Le défaut est que la présence de ce registre fait que les barrettes ont un temps de latence est plus important que celui des barrettes normales, du fait de la latence du registre.
Les barrettes de ce genre sont appelées des '''barrettes RIMM'''. Il en existe deux types :
* Avec les '''barrettes RDIMM''', le registre fait l'interface pour le bus d'adresse et le bus de commande, mais pas pour le bus de données.
* Avec les '''barrettes LRDIMM''' (''Load Reduced DIMMs''), le registre fait tampon pour tous les bus, y compris le bus de données.
[[File:Organisation des bus de commandes sur les RDIMM.png|centre|vignette|upright=3.0|Organisation des bus de commandes sur les RDIMM.]]
===Le ''Serial Presence Detect''===
[[File:SPD SDRAM.jpg|vignette|Localisation du SPD sur une barrette de SDRAM.]]
Toute barrette de mémoire assez récente contient une petite mémoire ROM qui stocke les différentes informations sur la mémoire : délais mémoire, capacité, marque, etc. Cette mémoire s'appelle le '''''Serial Presence Detect''''', aussi communément appelé le SPD. Ce SPD contient non seulement les timings de la mémoire RAM, mais aussi diverses informations, comme le numéro de série de la barrette, sa marque, et diverses informations. Le SPD est lu au démarrage de l'ordinateur par le BIOS, afin de pourvoir configurer ce qu'il faut.
Le contenu de ce fameux SPD est standardisé par un organisme nommé le JEDEC, qui s'est chargé de standardiser le contenu de cette mémoire, ainsi que les fréquences, timings, tensions et autres paramètres des mémoires SDRAM et DDR. Pour les curieux, vous pouvez lire la page wikipédia sur le SPD, qui donne son contenu pour les mémoires SDR et DDR : [https://en.wikipedia.org/wiki/Serial_presence_detect Serial Presence Detect].
==Les eDRAM : des DRAM adaptées aux ''chiplets''==
Les '''mémoires eDRAM''', pour ''embedded DRAM'', sont des mémoires RAM qui sont destinées à être intégrée au processeur. Pour comparer, les DRAM normales sont placées sur des barrettes de RAM ou soudées à la carte mère. Dans la quasi-totalité des cas, l'eDRAM est utilisée pour implémenter une mémoire cache, elle ne sert pas de mémoire principale (cache L4, le plus proche de la mémoire sur ces puces). De ce fait, elles sont conçues pour être très rapides, avoir une grande bande passante, au détriment de leur capacité mémoire.
Pour être plus précis, l'eDRAM est une puce de DRAM conçue pour être intégrée dans un ''chiplet'', , à savoir des circuits imprimés qui regroupent plusieurs puces électroniques distinctes, regroupées sur le même PCB. Typiquement, un processeur de type ''chiplet'' avec de l'eDRAM comprend deux puces séparées : une pour le processeur, une autre pour une puce de communication avec la RAM. Avec la mémoire eDRAM, les deux puces sont complétées par une troisième puce spécialisée qui incorpore l'eDRAM.
Elle a été utilisée sur quelques processeurs, mais aussi dans des consoles de jeu vidéo, pour la carte graphique des consoles suivantes : la PlayStation 2, la PlayStation Portable, la GameCube, la Wii, la Wii U, et la XBOX 360. Sur ces consoles, la RAM de la carte graphique était intégrée avec le processeur graphique dans le même circuit. La fameuse mémoire vidéo et le GPU n'étaient qu'une seule et même puce électronique, un seul circuit intégré. Ce n'est pas le cas sur une carte graphique moderne : regardez votre carte graphique avec attention et vous verrez que le GPU est une puce carrée située sous les ventilateurs, alors que les puces mémoires sont situées juste autour et soudées sur le PCB de la carte.
Les processeurs Intel Core de microarchitecture Broadwell disposaient d'un cache L4 de 128 mébioctets, intégralement implémenté avec de la mémoire eDRAM. Quelques processeurs de la microarchitecture précédente (Haswell), disposaient aussi de ce cache. Le cache L4 eDRAM était implémenté sur un chiplet à part, à savoir que le processeur était composé de trois puces séparées : une pour le processeur, une autre pour la gestion des entrées-sorties, et une autre pour le cache L4. La puce pour le cache L4 était appelée ''Crystal Well''. La puce ''Crystal Well'' était une puce gravée en 22nm, ce qui était une finesse de gravure plus élevée que celle des processeurs associés.
''Crystal Well'' était très optimisé pour l'époque. Par exemple, elle disposait de bus séparées pour la lecture et l'écriture, chose qu'on retrouve fréquemment sur les SRAM mais qui est absent sur les mémoires DRAM actuelles. Pour le reste, elle ressemblait beaucoup aux mémoires DDR de l'époque (système de ''double data rate'', entres autres), mais elle allait à une fréquence plus élevée que les DRAM de l'époque et avait un débit bien plus élevé, pour une consommation moindre. ''Crystal Well'' consommait entre 1 à 5 watts (1 watt en veille, 5 à pleine utilisation), pour un débit binaire de 102 GB/s et fonctionnait à 3.2 GHz.
<noinclude>
{{NavChapitre | book=Fonctionnement d'un ordinateur
| prev=Les mémoires SRAM synchrones
| prevText=Les mémoires SRAM synchrones
| next=Contrôleur mémoire externe
| nextText=Le contrôleur mémoire externe
}}{{autocat}}
</noinclude>
9wel9fztvln6py3xyi7xdbqfnwu4gvw
Programmation PHP avec Symfony/API
0
72921
764398
742376
2026-04-22T10:09:35Z
JackPotte
5426
/* API Platform */
764398
wikitext
text/x-wiki
<noinclude>{{Symfony}}</noinclude>
Pour créer une {{w|interface de programmation}} (API) {{w|Representational state transfer|REST}} avec Symfony, il existe plusieurs bibliothèques :
* {{w|API Platform}}<ref>https://api-platform.com/</ref>, tout-en-un qui utilise les attributs PHP (ou des annotations en PHP < 8) des entités pour créer les APIs (donc pas besoin de créer des contrôleurs ou autres). Par défaut il permet de sérialiser les flux en JSON (dont JSON-LD, JSON-HAL, JSON:API), XML (dont HTML), CSV, YAML, et même en GraphQL<ref>https://api-platform.com/docs/core/content-negotiation/</ref>.
* Sinon il faut combiner plusieurs éléments : routeur, générateur de doc en ligne et sérialiseur.
== API Platform ==
=== Installation ===
<pre>
composer require api
</pre>
=== Utilisation ===
{{attention|Le GraphQL de la version 1.1 passe par le schéma REST, et ne bénéficie donc pas du gain de performances attendu sans ''overfetching''.}}
{{attention|En REST, quand une valeur est null en base de données, pour alléger le flux, par défaut API Platform ne renvoie pas la clé du tout dans son résultat (alors qu'on pourrait s'attendre à avoir la clé avec une valeur null).}}
En bref, les routes d'API sont définies depuis les entités Doctrine.
Pour ajouter des fonctionnalités supplémentaires aux create/read/update/delete, il faut passer par des ''data providers''<ref>https://api-platform.com/docs/core/data-providers/</ref> ou des ''data persisters''<ref>https://api-platform.com/docs/core/data-persisters/</ref>, pour transformer les données, respectivement à l'affichage et à la sauvegarde.
==== Sécurité ====
Par défaut toutes les routes sont accessibles sans identification (selon security.yaml). Pour changer cela, on peut utiliser les ''Custom Doctrine ORM Extension''<ref>https://api-platform.com/docs/core/extensions/#custom-doctrine-orm-extension</ref> :
<pre>
class CurrentApiUserExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{ ... }
</pre>
==== Attributs ====
===== ApiResource =====
Définit les noms et méthodes REST (GET, POST...) des routes de l'API.
Exemple sur la V3<ref>https://api-platform.com/docs/core/operations/</ref> :
<pre>
#[ApiResource(
operations: [
new Get(),
new GetCollection()
]
)]
class MyEntity...
</pre>
Avec personnalisation de la vue OpenAPI :
<pre>
#[ApiResource(
operations: [
new Get(),
new GetCollection(),
],
openapiContext: [
'summary' => '',
'tags' => ['Enums'],
]
)]
</pre>
{{(|Idem sur la V2}}
<pre>
#[ApiResource(
collectionOperations: [
'get' => [
'openapiContext' => [
'summary' => '',
'tags' => ['Enums'],
],
],
],
itemOperations: [
'get' => [
'openapiContext' => [
'summary' => '',
'tags' => ['Enums'],
],
],
],
)]
</pre>
{{)}}
===== ApiProperty =====
Par exemple pour masquer un champ d'entité sur la route d'API :
<pre>
#[ApiProperty(readable: false, writable: false, required: false, fetchable: false)]
</pre>
===== MaxDepth =====
Définit le niveau de sérialisation d'un élément lié. Par exemple, si un client a plusieurs contrats et que ses contrats ont plusieurs produits, un ''MaxDepth(1)'' sur l'attribut ''client->contrat'' fera que la liste des clients comprendra tous les contrats mais pas leurs produits.
===== Évènements =====
API Platform ajoute plus d'une dizaine d'évènements donc les priorités sont définies dans EventPriorities<ref>https://api-platform.com/docs/core/events/</ref>.
Par exemple, pour modifier un JSON POST envoyé, utiliser EventPriorities::PRE_DESERIALIZE.
L'évènement suivant POST_DESERIALIZE contient les objets instanciés à partir du JSON.
== Triplet de bibliothèques ==
=== Installation ===
==== FOS REST ====
FOSRestBundle apporte des annotations pour créer des contrôleurs d'API<ref>https://github.com/FriendsOfSymfony/FOSRestBundle</ref>. Installation :
composer require "friendsofsymfony/rest-bundle"
Puis dans <u>config/packages/fos_rest.yaml</u> :
<syntaxhighlight lang=yaml>
fos_rest:
view:
view_response_listener: true
format_listener:
rules:
- { path: '^/', prefer_extension: true, fallback_format: ~, priorities: [ 'html', '*/*'] }
- { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json ] }
</syntaxhighlight>
==== Documentation ====
Toute API doit exposer sa documentation avec ses routes et leurs paramètres. NelmioApiDocBundle est un de générateur de documentation automatique à partir du code<ref>https://github.com/nelmio/NelmioApiDocBundle</ref>, qui permet en plus de tester en ligne. En effet, pour éviter de tester les API en copiant-collant leurs chemins dans une commande {{w|cURL}} ou dans des logiciels plus complets comme Postman<ref>https://www.postman.com/</ref>, on peut installer une interface graphique ergonomique qui allie documentation et test en ligne :
<pre>
composer require "nelmio/api-doc-bundle"
</pre>
Son URL se configure ensuite dans <u>routes/nelmio_api_doc.yml</u> :
<syntaxhighlight lang=yaml>
app.swagger_ui:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
</syntaxhighlight>
À ce stade l'URL /api/doc affiche juste un lien ''NelmioApiDocBundle''. Mais si les contrôleurs d'API sont identifiés dans annotations.yaml (avec un préfixe "api"), on peut voir une liste automatique de toutes leurs routes.
{{attention|Pour documenter /api/* sauf /api/doc, il faut préciser l'exception en regex dans <u>packages/nelmio_api_doc.yaml</u> :}}
<syntaxhighlight lang=yaml>
nelmio_api_doc:
areas:
path_patterns:
- ^/api/(?!/doc$)
</syntaxhighlight>
{{attention|Il faut vider le cache de Symfony à chaque modification de nelmio_api_doc.yaml.}}
===== Authentification =====
Pour tester depuis la documentation des routes nécessitant un token JWT, ajouter dans <u>packages/nelmio_api_doc.yaml</u> :
<syntaxhighlight lang=yaml>
nelmio_api_doc:
documentation:
securityDefinitions:
Bearer:
type: apiKey
description: 'Value: Bearer {jwt}'
name: Authorization
in: header
security:
- Bearer: []
</syntaxhighlight>
Il devient alors possible de renseigner le token avant de tester.
{{remarque|Si par défaut (sans configuration) on voit juste un champ "JWT (http, Bearer)" non envoyé depuis l'API doc, ajouter le paragraphe suivant pour qu'il le soit :
<pre>
security:
- JWT: []
</pre>
===== Exemple =====
Dans un contrôleur, au-dessus de l'attribut <code>#[Route]</code> d'un CRUD :
<pre>
use OpenApi\Attributes as OA;
...
#[OA\Post(
requestBody: new OA\RequestBody(
required: true,
content: [
new OA\JsonContent(
examples: [
new OA\Examples('1', summary: 'By ID', value: '{ "myEntity": { "id": 1 }}'),
new OA\Examples('2', summary: 'By name', value: '{ "myEntity": { "name": "TEST" }}'),
],
type: 'object',
),
],
),
tags: ['MyEntities'],
responses: [
new OA\Response(
response: Response::HTTP_OK,
description: 'Returns myEntity information.',
content: new OA\JsonContent(
properties: [
new OA\Property(
property: "id",
type: "integer",
example: 1,
nullable: true
),
new OA\Property(
property: "name",
type: "string",
example: 'TEST',
nullable: true
),
]
)
),
new OA\Response(
response: Response::HTTP_NOT_FOUND,
description: 'Returns no myEntity.',
content: new OA\JsonContent(
properties: [
new OA\Property(
property: "id",
type: "integer",
example: null,
nullable: true
),
]
)
)
]
)]
</pre>
==== Sérialiseur ====
Enfin pour la {{wt|sérialisation}}, on distingue plusieurs solutions :
* symfony/serializer, qui donne des contrôleurs <code>extends AbstractFOSRestController</code> et des méthodes aux annotations <code>@Rest\Post()</code><ref>https://www.thinktocode.com/2018/03/26/symfony-4-rest-api-part-1-fosrestbundle/</ref>.
* jms/serializer-bundle, avec des contrôleurs <code>extends RestController</code> et des méthodes aux annotations <code>@ApiDoc()</code>.
* Le service <code>fos_rest.service.serializer</code>.
===== symfony/serializer =====
<pre>
composer require "symfony/serializer"
</pre>
===== jms/serializer-bundle =====
<pre>
composer require "jms/serializer-bundle"
</pre>
=== Utilisation ===
Maintenant /api/doc affiche les méthodes des différents contrôleurs API. Voici un exemple :
<syntaxhighlight lang=php>
<?php
namespace App\Controller;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\View\View;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class APIController extends AbstractFOSRestController
{
#[Route('/api/test', methods: ['GET'])]
public function testAction(Request $request): View
{
return View::create('ok');
}
}
</syntaxhighlight>
{{(|Dans PHP < 8}}
<syntaxhighlight lang=php>
...
/**
* @Route("/api/test", methods={"GET"})
*/
public function testAction(Request $request): View
...
}
</syntaxhighlight>
{{)}}
Maintenant dans /api/doc, cliquer sur /api/test, puis "Ty it out" pour exécuter la méthode de test.
== Sécurité ==
Une API étant ''stateless'', l'authentification est assurée à chaque requête, par l'envoi par le client d'un token {{w|JSON Web Token}} (JWT) dans l'en-tête HTTP (clé ''Authorization''). Côté serveur, on transforme ensuite le JWT reçu en objet utilisateur pour accéder à l'identité du client au sein du code. Ceci est fait en configurant security.yaml, pour qu'un évènement firewall appelle automatiquement un guard authenticator<ref>https://symfony.com/doc/current/security/guard_authentication.html</ref> :
<pre>
composer require "symfony/security-bundle"
</pre>
<syntaxhighlight lang=yaml>
security:
firewalls:
main:
guard:
authenticators:
- App\Security\TokenAuthenticator
</syntaxhighlight>
=== Manipuler les JWT ===
Pour décrypter le JWT :
<pre>
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface;
...
public function __construct(
private readonly JWTEncoderInterface $jwtEncoder,
) {
}
public function decodeJwt(string $jwt): array
{
return $this->jwtEncoder->decode($jwt):
}
</pre>
Résultat minimum :
<pre>
array:6 [
"iat" => 1724677672
"exp" => 1724764072
"roles" => array:1 [
0 => "ROLE_INACTIF"
]
"username" => "test"
]
</pre>
Si on n'a pas besoin de vérifier le JWT (validité, expiration et signature modifiée par un pirate), on peut se passer de Lexik ainsi :
<pre>
private function decodeJwt(string $jwt): array|bool|null
{
$tokenParts = explode('.', $jwt);
if (empty($tokenParts[1])) {
return [];
}
$tokenPayload = base64_decode($tokenParts[1]);
return json_decode($tokenPayload, true);
}
</pre>
=== Test ===
Pour tester en shell :
<pre>
TOKEN=123
curl -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}" http://localhost
</pre>
== Références ==
{{Références}}
d72e0kasxj4mfel290lool2dstfc0i0
Utilisateur:Agrodata/Agrodatabase
2
73836
764350
758600
2026-04-22T08:46:06Z
JackPotte
5426
Réparation du lien
764350
wikitext
text/x-wiki
{{Suppression_Immédiate|1=Cross-wiki spam. See [[:m:Steward_requests/Miscellaneous/2026-02#Agrodata]].}}
{{version imprimable}}
# [[/1. 0 - Introduction /]]
# [[/2. 10 - Système de classification agricole /]]
20 - Prontuaire culture
# [[/201 - Groupes de cultures /]]
# [[/202 -Sujets, Unités et Évaluations /]]
# [[/21 - Prontuaire culture - Données /]]
# [[/22 -Prontuaire culture- Évaluation /]]
40 - Pathogènes
# [[/41 - Nom scientifique des agents pathogènes /]]
# [[/42 - Pathogènes - Taxonomie /]]
# [[/43 - Taxonomie - Pathogènes /]]
# [[/43 - Pathogènes synonyme de nom scientifique /]]
54 - Pharmacologie agricole
# [[/541 - Substances actives - Propriétés /]]
# [[/542 - Propriétés - Substances actives /]]
# [[/543 - Cultures - Pathogènes /]]
# [[/544 - Cultures - Pathogènes - Substances actives /]]
55 - Engrais
# [[/551 - Tables d'engrais /]]
71 - Prontuaire des pâturages tropicaux
# [[/711 - Prontuaire des pâturages tropicaux - Données /]]
# [[/712 - Prontuaire des pâturages tropicaux - Évaluation /]]
91 - Dictionnaire paneuropéen des produits agricoles
# [[/911 - Classement des produits agricoles par groupes /]]
# [[/912 - Français - langue européenne /]]
# [[/913 - Langue européenne - Français /]]
92 - Entreprises agrochimiques du Web
# [[/921 - Pays - Entreprises agrochimiques /]]
# [[/922 - Entreprises agrochimiques - Pays /]]
93 - AgroWipedia
# [[/931 - Cultures Wikipedia /]]
# [[/932 - Wikipedia pathogènes /]]
# [[/933 - Substances phytosanitaires Wikipedia /]]
{{AutoCat}}
fuqfb0z5m4eo1uvlh79vtnde5izz1ec
764351
764350
2026-04-22T08:54:23Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase]] vers [[Utilisateur:Agrodata/Agrodatabase]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
764350
wikitext
text/x-wiki
{{Suppression_Immédiate|1=Cross-wiki spam. See [[:m:Steward_requests/Miscellaneous/2026-02#Agrodata]].}}
{{version imprimable}}
# [[/1. 0 - Introduction /]]
# [[/2. 10 - Système de classification agricole /]]
20 - Prontuaire culture
# [[/201 - Groupes de cultures /]]
# [[/202 -Sujets, Unités et Évaluations /]]
# [[/21 - Prontuaire culture - Données /]]
# [[/22 -Prontuaire culture- Évaluation /]]
40 - Pathogènes
# [[/41 - Nom scientifique des agents pathogènes /]]
# [[/42 - Pathogènes - Taxonomie /]]
# [[/43 - Taxonomie - Pathogènes /]]
# [[/43 - Pathogènes synonyme de nom scientifique /]]
54 - Pharmacologie agricole
# [[/541 - Substances actives - Propriétés /]]
# [[/542 - Propriétés - Substances actives /]]
# [[/543 - Cultures - Pathogènes /]]
# [[/544 - Cultures - Pathogènes - Substances actives /]]
55 - Engrais
# [[/551 - Tables d'engrais /]]
71 - Prontuaire des pâturages tropicaux
# [[/711 - Prontuaire des pâturages tropicaux - Données /]]
# [[/712 - Prontuaire des pâturages tropicaux - Évaluation /]]
91 - Dictionnaire paneuropéen des produits agricoles
# [[/911 - Classement des produits agricoles par groupes /]]
# [[/912 - Français - langue européenne /]]
# [[/913 - Langue européenne - Français /]]
92 - Entreprises agrochimiques du Web
# [[/921 - Pays - Entreprises agrochimiques /]]
# [[/922 - Entreprises agrochimiques - Pays /]]
93 - AgroWipedia
# [[/931 - Cultures Wikipedia /]]
# [[/932 - Wikipedia pathogènes /]]
# [[/933 - Substances phytosanitaires Wikipedia /]]
{{AutoCat}}
fuqfb0z5m4eo1uvlh79vtnde5izz1ec
764393
764351
2026-04-22T08:56:27Z
JackPotte
5426
764393
wikitext
text/x-wiki
{{Suppression_Immédiate|1=Cross-wiki spam. See [[:m:Steward_requests/Miscellaneous/2026-02#Agrodata]].}}
# [[/1. 0 - Introduction /]]
# [[/2. 10 - Système de classification agricole /]]
20 - Prontuaire culture
# [[/201 - Groupes de cultures /]]
# [[/202 -Sujets, Unités et Évaluations /]]
# [[/21 - Prontuaire culture - Données /]]
# [[/22 -Prontuaire culture- Évaluation /]]
40 - Pathogènes
# [[/41 - Nom scientifique des agents pathogènes /]]
# [[/42 - Pathogènes - Taxonomie /]]
# [[/43 - Taxonomie - Pathogènes /]]
# [[/43 - Pathogènes synonyme de nom scientifique /]]
54 - Pharmacologie agricole
# [[/541 - Substances actives - Propriétés /]]
# [[/542 - Propriétés - Substances actives /]]
# [[/543 - Cultures - Pathogènes /]]
# [[/544 - Cultures - Pathogènes - Substances actives /]]
55 - Engrais
# [[/551 - Tables d'engrais /]]
71 - Prontuaire des pâturages tropicaux
# [[/711 - Prontuaire des pâturages tropicaux - Données /]]
# [[/712 - Prontuaire des pâturages tropicaux - Évaluation /]]
91 - Dictionnaire paneuropéen des produits agricoles
# [[/911 - Classement des produits agricoles par groupes /]]
# [[/912 - Français - langue européenne /]]
# [[/913 - Langue européenne - Français /]]
92 - Entreprises agrochimiques du Web
# [[/921 - Pays - Entreprises agrochimiques /]]
# [[/922 - Entreprises agrochimiques - Pays /]]
93 - AgroWipedia
# [[/931 - Cultures Wikipedia /]]
# [[/932 - Wikipedia pathogènes /]]
# [[/933 - Substances phytosanitaires Wikipedia /]]
s7zjq1eo3e8uo1fyne6assrnmrq7nxf
764394
764393
2026-04-22T08:58:12Z
JackPotte
5426
764394
wikitext
text/x-wiki
# [[/1. 0 - Introduction /]]
# [[/2. 10 - Système de classification agricole /]]
20 - Prontuaire culture
# [[/201 - Groupes de cultures /]]
# [[/202 -Sujets, Unités et Évaluations /]]
# [[/21 - Prontuaire culture - Données /]]
# [[/22 -Prontuaire culture- Évaluation /]]
40 - Pathogènes
# [[/41 - Nom scientifique des agents pathogènes /]]
# [[/42 - Pathogènes - Taxonomie /]]
# [[/43 - Taxonomie - Pathogènes /]]
# [[/43 - Pathogènes synonyme de nom scientifique /]]
54 - Pharmacologie agricole
# [[/541 - Substances actives - Propriétés /]]
# [[/542 - Propriétés - Substances actives /]]
# [[/543 - Cultures - Pathogènes /]]
# [[/544 - Cultures - Pathogènes - Substances actives /]]
55 - Engrais
# [[/551 - Tables d'engrais /]]
71 - Prontuaire des pâturages tropicaux
# [[/711 - Prontuaire des pâturages tropicaux - Données /]]
# [[/712 - Prontuaire des pâturages tropicaux - Évaluation /]]
91 - Dictionnaire paneuropéen des produits agricoles
# [[/911 - Classement des produits agricoles par groupes /]]
# [[/912 - Français - langue européenne /]]
# [[/913 - Langue européenne - Français /]]
92 - Entreprises agrochimiques du Web
# [[/921 - Pays - Entreprises agrochimiques /]]
# [[/922 - Entreprises agrochimiques - Pays /]]
93 - AgroWipedia
# [[/931 - Cultures Wikipedia /]]
# [[/932 - Wikipedia pathogènes /]]
# [[/933 - Substances phytosanitaires Wikipedia /]]
a7jf4hwlnegztmomkvtnig9j30hwa1z
Utilisateur:Agrodata/Agrodatabase/911 - Classement des produits agricoles par groupes
2
73838
764389
628105
2026-04-22T08:54:29Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/911 - Classement des produits agricoles par groupes]] vers [[Utilisateur:Agrodata/Agrodatabase/911 - Classement des produits agricoles par groupes]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
628105
wikitext
text/x-wiki
# [[/ Allemand /]]
# [[/ Anglais /]]
# [[/ Bulgare /]]
# [[/ Danois /]]
# [[/ Espagnol /]]
# [[/ Estonie /]]
# [[/ Finlande /]]
# [[/ Grec /]]
# [[/ Hongrois /]]
# [[/ Italien /]]
# [[/ Letton /]]
# [[/ Lituanien /]]
# [[/ Néerlandais /]]
# [[/ Polonais /]]
# [[/ Portugais /]]
# [[/ Roumain /]]
# [[/ Scientifique /]]
# [[/ Slovaque /]]
# [[/ Slovène /]]
# [[/ Suède /]]
# [[/ Tchèque /]]
{{AutoCat}}
rt2olj3fiqm3hw00xlvmh1mf7to86fj
Utilisateur:Agrodata/Agrodatabase/912 - Français - langue européenne
2
73839
764390
628106
2026-04-22T08:54:29Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/912 - Français - langue européenne]] vers [[Utilisateur:Agrodata/Agrodatabase/912 - Français - langue européenne]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
628106
wikitext
text/x-wiki
# [[/ Français-Allemand /]]
# [[/ Français-Anglais /]]
# [[/ Français-Bulgare /]]
# [[/ Français-Danois /]]
# [[/ Français-Espagnol /]]
# [[/ Français-Estonie /]]
# [[/ Français-Finlande /]]
# [[/ Français-Grec /]]
# [[/ Français-Hongrie /]]
# [[/ Français-Italienne /]]
# [[/ Français-Lettonie /]]
# [[/ Français-Lituanie /]]
# [[/ Français-Néerlandais /]]
# [[/ Français-Polonais /]]
# [[/ Français-Portugais /]]
# [[/ Français-Roumaine /]]
# [[/ Français-Scientifique /]]
# [[/ Français-Slovaque /]]
# [[/ Français-Slovène /]]
# [[/ Français-Suède /]]
# [[/ Français-Tchèque /]]
{{AutoCat}}
g2thhn1ma3bcgac0sugy34a8jqxe303
Utilisateur:Agrodata/Agrodatabase/913 - Langue européenne - Français
2
73840
764391
628107
2026-04-22T08:54:29Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/913 - Langue européenne - Français]] vers [[Utilisateur:Agrodata/Agrodatabase/913 - Langue européenne - Français]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
628107
wikitext
text/x-wiki
# [[/ Allemand-Français /]]
# [[/ Anglais-Français /]]
# [[/ Bulgare-Français /]]
# [[/ Danois-Français /]]
# [[/ Espagnol-Français /]]
# [[/ Estonie-Français /]]
# [[/ Finlande-Français /]]
# [[/ Grec-Français /]]
# [[/ Hongrie-Français /]]
# [[/ Italienne-Français /]]
# [[/ Lettonie-Français /]]
# [[/ Lituanie-Français /]]
# [[/ Néerlandais-Français /]]
# [[/ Polonais-Français /]]
# [[/ Portugais-Français /]]
# [[/ Roumaine-Français /]]
# [[/ Scientifique-Français /]]
# [[/ Slovaque-Français /]]
# [[/ Slovène-Français /]]
# [[/ Suède-Français /]]
# [[/ Tchèque-Français /]]
{{AutoCat}}
h9xep4ysjmgr6fk3bpvd2y7hxy1eled
Utilisateur:Agrodata/Agrodatabase/541 - Substances actives - Propriétés
2
73882
764388
628104
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/541 - Substances actives - Propriétés]] vers [[Utilisateur:Agrodata/Agrodatabase/541 - Substances actives - Propriétés]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
628104
wikitext
text/x-wiki
{|
|| ABAMECTINE
|| LARVES ET ADULTES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE
|-
|| ACEPHATE
|| CONTACT-ADMISSION / ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| ACÉTAMIPRIDE
|| TOUS LES STADES / CONTACT-ADMISSION / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| ACIBENZOLAR-S-MÉTHYLE
|| SYSTÉMIQUE
|-
|| ACRINATHRINE
|| LARVES ET ADULTES / CONTACT-ADMISSION / ÉRADICATIF / PERSISTANCE-RÉSIDUEL
|-
|| ALFA CYPERMÉTHRINE
|| LARVES ET ADULTES / CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| AMITRAZE
|| CONTACT-ADMISSION / PERSISTANCE-RÉSIDUEL
|-
|| AZADIRACHTINE
|| LARVES / CONTACT-ADMISSION ET REPELLENT
|-
|| AZOCYCLOTINE
|| LARVES / CONTACT / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| AZOXYSTROBINE
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| BACILLUS SUBTILIS
|| CONTACT-ADMISSION-INHALATION / ÉRADICATIF-PREVENTIVE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| BENFURACARB
|| CONTACT-ADMISSION / ACROPÈTE (CROISSANT -XYLÈME) / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL
|-
|| BENOMYL
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PÉNÉTRATION RAPIDE / APPLICATION AU SOL / LARGE SPECTRE
|-
|| BÉTA CYFLUTHRINE
|| CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF / NON SYSTÉMIQUE / NON PÉNÉTRANT / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| BETA-CYPERMETHRINE
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| BIFENTHRIN
|| LARVES ET ADULTES / CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| BITERTANOL
|| CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| BOSCALID
|| PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| BROMOPROPYLATE
|| OEUFS / SPÉCIFIQUE
|-
|| BUPIRIMATE
|| INHALATION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| BUPROFEZINE
|| LARVES / CONTACT-ADMISSION-INHALATION / PRÉVENTIFS / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL
|-
|| CADUSAFOS
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / APPLICATION AU SOL / LARGE SPECTRE
|-
|| CAPTANE
|| CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CARBARYL
|| CONTACT-ADMISSION / PRÉVENTIFS-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| CARBENDAZIM
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / NON RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CARBOFURAN
|| CONTACT-ADMISSION / ÉRADICATIF / SYSTÉMIQUE / APPLICATION AU SOL / LARGE SPECTRE
|-
|| CARBOSULFAN
|| CONTACT-ADMISSION / SYSTÉMIQUE / APPLICATION AU SOL / LARGE SPECTRE
|-
|| CARTAP
|| CONTACT-ADMISSION / SYSTÉMIQUE
|-
|| CHLORANTRANILIPROLE
|| OEUFS ET LARVES / CONTACT-ADMISSION / ÉRADICATIF-PREVENTIVE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CHLORFENAPYR
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| CHLORFLUAZURON.
|| LARVES / ADMISSION / SYSTÉMIQUE
|-
|| CHLOROTHALONIL
|| CONTACT / ÉRADICATIF-PREVENTIVE / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CHLORPYRIFOS
|| CONTACT-ADMISSION-INHALATION / ÉRADICATIF / NON SYSTÉMIQUE / PÉNÉTRATION RAPIDE / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CHLORPYRIPHOS-MÉTHYL
|| CONTACT-ADMISSION-INHALATION / ÉRADICATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| CLOFENTÉZINE
|| OEUFS ET LARVES / CONTACT / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| CLOTHIANIDIN
|| CONTACT-ADMISSION / PRÉVENTIFS / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE ET SOL / LARGE SPECTRE
|-
|| CUPRIC OXYCHLORIDE
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| CYAZOFAMIDE
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT
|-
|| CYFLUTHRINE
|| CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| CYHEXATIN
|| LARVES ET ADULTES / CONTACT-ADMISSION / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| CYMOXANIL
|| CONTACT / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE RAPIDE / PEU PERSISTANCE / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| CYPERMÉTHRINE
|| CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CYPROCONAZOLE
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / CROISSANT-VERS LE BAS / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CYPRODINIL
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE RAPIDE / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| CYROMAZINE
|| LARVES / CONTACT-ADMISSION / ACROPÈTE (CROISSANT -XYLÈME) / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / SPÉCIFIQUE
|-
|| DELTAMÉTHRINE
|| LARVES ET ADULTES / CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| DIAFENTHIURON.
|| CONTACT-ADMISSION / LARGE SPECTRE
|-
|| DIAZINON
|| CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / APPLICATION AU SOL / LARGE SPECTRE
|-
|| DICOFOL
|| LARVES ET ADULTES / CONTACT / ÉRADICATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| DIETHOFENCARB
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / PERSISTANCE-RÉSIDUEL
|-
|| DIFENOCONAZOLE
|| PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / MÉSOSTÉMIQUE ET TRANSLAMINAIRE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| DIFLUBENZURON
|| OEUFS ET LARVES / CONTACT-ADMISSION / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| DIMETHOATE
|| CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / MÉSOSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| DIMÉTOMORPHE
|| CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| DINICONAZOLE
|| INHALATION / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| DINOCAP
|| LARVES ET ADULTES / CONTACT / PRÉVENTIFS-CURATIF
|-
|| DITHIANON
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT / PÉNÉTRATION ABSORPTION / PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE
|-
|| DODEMORPH
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE
|-
|| DODINE
|| ÉRADICATIF-PREVENTIVE / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| EMAMECTINE
|| LARVES / CONTACT-ADMISSION / NON SYSTÉMIQUE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| ENDOSULFAN
|| CONTACT-ADMISSION / PRÉVENTIFS / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| EPOXICONAZOLE
|| LARVES ET ADULTES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / MÉSOSTÉMIQUE ET TRANSLAMINAIRE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE /
|-
|| ESFENVALÉRATE
|| CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| ETHABOXAM
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE
|-
|| ETHOPROPHOS
|| CONTACT-ADMISSION-INHALATION / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / APPLICATION AU SOL / LARGE SPECTRE
|-
|| ETHYRIMOL
|| CONTACT-ADMISSION
|-
|| ÉTOFENPROX
|| CONTACT-ADMISSION / ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| ÉTOXAZOLE
|| OEUFS ET LARVES / CONTACT-ADMISSION / SYSTÉMIQUE / TRANSLAMINAIRE RAPIDE / LARGE SPECTRE
|-
|| ÉTRIDIAZOLE
|| CONTACT / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / APPLICATION AU SOL
|-
|| FAMOXADONE
|| CONTACT-ADMISSION-INHALATION / PRÉVENTIFS / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FÉNAMIDONE
|| PRÉVENTIFS-CURATIF / LARGE SPECTRE
|-
|| FENAMIPHOS
|| CONTACT-ADMISSION / SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FENARIMOL
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / LARGE SPECTRE
|-
|| FÉNAZAQUINE
|| TOUS LES STADES / CONTACT-ADMISSION / ÉRADICATIF / PERSISTANCE-RÉSIDUEL
|-
|| FENBUCONAZOLE
|| INHALATION / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / MÉSOSTÉMIQUE ET TRANSLAMINAIRE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| FENBUTATIN OXYDE
|| LARVES ET ADULTES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FENHEXAMIDE
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FENITROTHION
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| FENOXICARBE
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| FENPROPIMORPHE
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| FENPROPIMORPHE
|| PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FENPYROXIMATE
|| LARVES ET ADULTES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| FENTINE HYDROXYDE
|| PRÉVENTIFS-CURATIF / MÉSOSTÉMIQUE
|-
|| FENVALERATE
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / PÉNÉTRATION RAPIDE / LARGE SPECTRE
|-
|| FERBAME
|| CONTACT-ADMISSION / SYSTÉMIQUE
|-
|| FIPRONIL
|| CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FLONICAMIDE
|| CONTACT / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| FLUAZINAM
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FLUBENDIAMIDE
|| LARVES / CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / LARGE SPECTRE
|-
|| FLUDIOXONIL
|| CONTACT / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| FLUFENOXURON
|| LARVES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE /
|-
|| FLUOPYRAM
|| PRÉVENTIFS / MÉSOSTÉMIQUE
|-
|| FLUOXASTROBINE
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / LARGE SPECTRE
|-
|| FLUQUINCONAZOLE
|| LARVES / ADMISSION / ÉRADICATIF-PREVENTIVE / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| FLUSILAZOLE
|| LARVES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / NON RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| FLUTRIAFOL
|| CONTACT-INHALATION / ÉRADICATIF-PREVENTIVE / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| FOLPET
|| CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL
|-
|| FORMETANATE
|| LARVES ET ADULTES / CONTACT-ADMISSION / NON SYSTÉMIQUE / NON PÉNÉTRANT / SPÉCIFIQUE
|-
|| FOSÉTYL-AL
|| TOUS LES STADES / CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / CROISSANT-VERS LE BAS / MÉSOSTÉMIQUE ET TRANSLAMINAIRE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| FOSTHIAZATE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE ET SOL
|-
|| FOXIME
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / APPLICATION AU SOL
|-
|| FTHALIDE
|| CONTACT-ADMISSION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| GAMMA-CYHALOTHRINE
|| CONTACT-ADMISSION ET REPELLENT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| HEXACONAZOLE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / LARGE SPECTRE
|-
|| HEXYTHIAZOX
|| OEUFS ET LARVES / CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| HYDROXYDE DE CUIVRE
|| CONTACT / PRÉVENTIFS / CROISSANT-VERS LE BAS / TRANSLAMINAIRE-PLUSIEURS LIEUX / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| HYMEXAZOL
|| SYSTÉMIQUE / APPLICATION AU SOL
|-
|| IMAZALIL
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| IMIBENCONAZOLE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL
|-
|| IMIDACLOPRIDE
|| OEUFS / CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / ABSORPTION FEUILLES-RACINES / MÉSOSTÉMIQUE ET TRANSLAMINAIRE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE /
|-
|| INDOXACARB
|| OEUFS ET LARVES / CONTACT-ADMISSION / PRÉVENTIFS-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| IPROBENFOS
|| PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE ET SOL
|-
|| IPRODIONE
|| LARVES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / CROISSANT-VERS LE BAS / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| ISOPROTHIOLANE.
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| KASUGAMYCINE
|| LARGE SPECTRE
|-
|| KASUGAMYCINE
|| SYSTÉMIQUE
|-
|| KRÉSOXIM-MÉTHYL
|| LARVES / CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| LAMBDA-CYHALOTHRINE
|| CONTACT-ADMISSION ET REPELLENT / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / NON SYSTÉMIQUE / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| LUFENURON
|| LARVES / ADMISSION / ÉRADICATIF-PREVENTIVE / NON SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| MALATHION
|| CONTACT-ADMISSION-INHALATION / ÉRADICATIF / NON SYSTÉMIQUE / PÉNÉTRATION RAPIDE / LARGE SPECTRE
|-
|| MANCOZÈBE
|| CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION / TRANSLAMINAIRE-PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| MANDIPROPAMID
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / CROISSANT-VERS LE BAS / PÉNÉTRATION RAPIDE / PERSISTANCE-RÉSIDUEL
|-
|| MANÈBE
|| PRÉVENTIFS / PLUSIEURS LIEUX / LARGE SPECTRE
|-
|| MEPANIPYRIM
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / LARGE SPECTRE
|-
|| MEPTYL DINOCAP
|| CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / SYSTÉMIQUE / LARGE SPECTRE
|-
|| METAFLUMIZONE
|| CONTACT-ADMISSION-INHALATION / LARGE SPECTRE
|-
|| METALAXYL
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / APPLICATION AU SOL
|-
|| METALAXYL-M
|| OEUFS ET LARVES / CONTACT-ADMISSION ET REPELLENT / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| MÉTALDÉHYDE
|| CONTACT-ADMISSION / PRÉVENTIFS / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| METCONAZOLE
|| CONTACT / PRÉVENTIFS
|-
|| MÉTHAM POTASSIUM
|| APPLICATION AU SOL / LARGE SPECTRE
|-
|| MÉTHAM SODIUM
|| CONTACT / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| MÉTHAMIDOPHOS
|| CONTACT / PRÉVENTIFS-ANTISPORULANT / LARGE SPECTRE
|-
|| MÉTHIDATHION
|| CONTACT-ADMISSION / NON SYSTÉMIQUE
|-
|| MÉTHIOCARBE
|| CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / NON PÉNÉTRANT / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| METHOMYL
|| CONTACT-ADMISSION / ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| METHOXYFENOZIDE
|| OEUFS ET LARVES / CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / LARGE SPECTRE
|-
|| METIL AZINFOS
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| MÉTIRAME
|| LARVES ET ADULTES / CONTACT-ADMISSION / PRÉVENTIFS / ACROPÈTE (CROISSANT -XYLÈME) / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| METRAFENONE
|| CONTACT / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME)
|-
|| MYCLOBUTANYL
|| CONTACT-ADMISSION ET REPELLENT / PREVENTIVE-CURATIF-ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| NALED
|| CONTACT-ADMISSION / NON SYSTÉMIQUE
|-
|| NOVALURON
|| CONTACT-ADMISSION
|-
|| OXAMYL
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| OXYCARBOXIN
|| CONTACT / SYSTÉMIQUE
|-
|| OXYCHLORURE CUIVRE CALCIUM
|| CONTACT / PRÉVENTIFS-ANTISPORULANT / LARGE SPECTRE
|-
|| OXYDE CUIVRIQUE (II)
|| PRÉVENTIFS-ANTISPORULANT / PLUSIEURS LIEUX / LARGE SPECTRE
|-
|| OXYDE DE CUIVRE(I)
|| PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PARAFFIN
|| OEUFS / CONTACT-ADMISSION / MÉSOSTÉMIQUE ET TRANSLAMINAIRE
|-
|| PENCONAZOLE
|| LARVES ET ADULTES / CONTACT-ADMISSION ET REPELLENT / PREVENTIVE-CURATIF-ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PENCYCURON
|| LARVES ET ADULTES / CONTACT-ADMISSION / ÉRADICATIF-PREVENTIVE / NON SYSTÉMIQUE / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PERMETHRIN
|| TOUS LES STADES / CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF-PREVENTIVE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PHORATE
|| CONTACT-ADMISSION / SYSTÉMIQUE
|-
|| PHOSALONE
|| CONTACT-ADMISSION / NON SYSTÉMIQUE
|-
|| PHOSMET
|| TOUS LES STADES / CONTACT-ADMISSION-INHALATION / ÉRADICATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL
|-
|| PICOXYSTROBINE
|| LARVES / CONTACT-ADMISSION ET REPELLENT / ÉRADICATIF-PREVENTIVE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PIRIMICARBE
|| CONTACT-ADMISSION-INHALATION / ÉRADICATIF-PREVENTIVE / ACROPÈTE (CROISSANT -XYLÈME) / PEU PERSISTANCE / LARGE SPECTRE
|-
|| PIRIMIPHOS-MÉTHYL
|| CONTACT-INHALATION / PRÉVENTIFS / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| POLYSULFIDE CALCIUM
|| PREVENTIVE-CURATIF-ÉRADICATIF-ANTISPORULANT / SYSTÉMIQUE
|-
|| PROCHLORAZE
|| CONTACT / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PROCYMIDONE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| PROFENOFOS
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| PROPAMOCARBE
|| LARVES / CONTACT-ADMISSION / PREVENTIVE-CURATIF-ÉRADICATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PROPARGITE
|| LARVES ET ADULTES / CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| PROPICONAZOLE
|| CONTACT / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PROPINEB
|| CONTACT / PRÉVENTIFS-CURATIF / PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PROQUINAZID
|| PRÉVENTIFS-CURATIF / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| PYMÉTROZINE
|| LARVES / CONTACT-ADMISSION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| PYRACLOSTROBINE
|| LARVES / CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PYRIDABEN
|| TOUS LES STADES / CONTACT / ÉRADICATIF-PREVENTIVE / NON SYSTÉMIQUE / NON PÉNÉTRANT / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| PYRIMÉTHANIL
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| PYRIPROXYFÈNE
|| LARVES / CONTACT-ADMISSION / ÉRADICATIF-PREVENTIVE / SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| QUILLAY EXTRACT
|| CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE
|-
|| QUINOXYFEN
|| INHALATION / PRÉVENTIFS / SYSTÉMIQUE
|-
|| SOUFRE
|| CONTACT-INHALATION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / NON PÉNÉTRANT / PEU PERSISTANCE / SPÉCIFIQUE
|-
|| SPINETORAM
|| CONTACT-ADMISSION / SYSTÉMIQUE / LARGE SPECTRE
|-
|| SPINOSAD
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| SPIRODICLOFEN
|| LARVES / CONTACT-ADMISSION ET REPELLENT / PREVENTIVE-CURATIF-ÉRADICATIF / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| SPIROMESIFEN
|| LARVES / CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| SPIROTETRAMAT
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| SPIROXAMINE
|| LARVES ET ADULTES / CONTACT-ADMISSION ET REPELLENT / PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| SULFATE CUIVRE CALCIUM
|| CONTACT / PRÉVENTIFS-ANTISPORULANT / LARGE SPECTRE
|-
|| SULFATE DE CUIVRE
|| PRÉVENTIFS-ANTISPORULANT / SYSTÉMIQUE / PLUSIEURS LIEUX / LARGE SPECTRE
|-
|| SULFATE TRIBASIQUE DE CUIVRE
|| CONTACT / PRÉVENTIFS-ANTISPORULANT / LARGE SPECTRE
|-
|| summer oil
|| OEUFS / CONTACT-ADMISSION / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| TAU-FLUVALINATE
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| TEBUCONAZOLE
|| TOUS LES STADES / CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| TEBUFENOZIDE
|| LARVES / CONTACT-ADMISSION-INHALATION / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| TEBUFENPYRAD
|| TOUS LES STADES / CONTACT-ADMISSION / ÉRADICATIF / NON SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE
|-
|| TEFLUBENZURON
|| LARVES ET ADULTES / CONTACT-ADMISSION / SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| TEFLUTHRINE
|| LARVES ET ADULTES / CONTACT-ADMISSION-INHALATION / PRÉVENTIFS-CURATIF-ANTISPORULANT / SYSTÉMIQUE / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / SPÉCIFIQUE
|-
|| TERBUFOS
|| LARVES / PRÉVENTIFS-CURATIF-ANTISPORULANT / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE
|-
|| TÉTRACONAZOLE
|| PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / PÉNÉTRATION RAPIDE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| TETRADIFON
|| OEUFS ET LARVES / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| THIABENDAZOLE
|| PRÉVENTIFS-CURATIF / ACROPÈTE (CROISSANT -XYLÈME) / TRANSLAMINAIRE-SYSTÉMIQUES LIEU / LARGE SPECTRE
|-
|| THIACLOPRIDE
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PÉNÉTRATION RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| THIAMETHOXAM
|| CONTACT-ADMISSION / PRÉVENTIFS / SYSTÉMIQUE / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| THIFLUZAMIDE
|| SYSTÉMIQUE / TRANSLAMINAIRE ET SOL / SPÉCIFIQUE
|-
|| THIOCYCLAM
|| CONTACT-ADMISSION / PRÉVENTIFS / LARGE SPECTRE
|-
|| THIODICARB
|| ADMISSION / LARGE SPECTRE
|-
|| THIOPHANATE MÉTHYLE
|| CONTACT-ADMISSION / PRÉVENTIFS-CURATIF-ANTISPORULANT / CROISSANT-VERS LE BAS / ABSORPTION FEUILLES-RACINES / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| THIRAME
|| CONTACT / PRÉVENTIFS-ANTISPORULANT / NON SYSTÉMIQUE / PLUSIEURS LIEUX / NON RÉSISTANT À LA PLUIE / LARGE SPECTRE
|-
|| TOLCLOFOS-MÉTHYL
|| CONTACT / PRÉVENTIFS-CURATIF / NON SYSTÉMIQUE / APPLICATION AU SOL / PERSISTANCE-RÉSIDUEL / SPÉCIFIQUE
|-
|| Tolylfluanid
|| PRÉVENTIFS / PLUSIEURS LIEUX / LARGE SPECTRE
|-
|| TRIADIMEFON
|| PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / LARGE SPECTRE
|-
|| TRIADIMÉNOL
|| PREVENTIVE-CURATIF-ÉRADICATIF / SYSTÉMIQUE / TRANSLAMINAIRE RAPIDE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| TRIAZOPHOS
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| TRICHLORFON
|| CONTACT-ADMISSION / NON SYSTÉMIQUE / LARGE SPECTRE
|-
|| TRICYCLAZOLE
|| PRÉVENTIFS / SYSTÉMIQUE / ABSORPTION FEUILLES-RACINES / TRANSLAMINAIRE ET SOL / PERSISTANCE-RÉSIDUEL / RÉSISTANT À LA PLUIE
|-
|| TRIDEMORPH
|| ÉRADICATIF / SYSTÉMIQUE
|-
|| TRIFLOXYSTROBINE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / PÉNÉTRATION RAPIDE / LARGE SPECTRE
|-
|| TRIFLUMIZOLE
|| CONTACT / PRÉVENTIFS-CURATIF / SYSTÉMIQUE / TRANSLAMINAIRE-SYSTÉMIQUES LIEU
|-
|| TRIFLUMURON
|| LARVES / CONTACT / NON SYSTÉMIQUE / PERSISTANCE-RÉSIDUEL / LARGE SPECTRE
|-
|| TRITICONAZOLE
|| SYSTÉMIQUE / LARGE SPECTRE
|-
|| Vinclozoline
|| PRÉVENTIFS-ANTISPORULANT / NON SYSTÉMIQUE / PÉNÉTRATION ABSORPTION
|-
|| ZETA CYPERMÉTHRINE
|| CONTACT-ADMISSION / NON SYSTÉMIQUE
|-
|| ZIRAME
|| CONTACT / PRÉVENTIFS / PLUSIEURS LIEUX / PERSISTANCE-RÉSIDUEL / NON RÉSISTANT À LA PLUIE
|}
{{AutoCat}}
eyqfskhnfn7ez3v07gtyfpm7cnyajsh
Utilisateur:Agrodata/Agrodatabase/201 - Groupes de cultures
2
74488
764352
634756
2026-04-22T08:54:23Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/201 - Groupes de cultures]] vers [[Utilisateur:Agrodata/Agrodatabase/201 - Groupes de cultures]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
634756
wikitext
text/x-wiki
{|
|| Id UE
|| -
|| '''Vegetables'''
|-
|| 15200
|| -
|| Fraises
|-
|| 21000
|| -
|| '''Tubercules'''
|-
|| 21100
|| -
|| Pommes de terre
|-
|| 21200
|| -
|| '''Tubercules tropicaux'''
|-
|| 21201
|| -
|| Manioc
|-
|| 21202
|| -
|| Patates douces
|-
|| 21203
|| -
|| Ignames
|-
|| 21300
|| -
|| '''Racines'''
|-
|| 21302
|| -
|| Carottes
|-
|| 21308
|| -
|| Radis
|-
|| 21311
|| -
|| Navets
|-
|| 22000
|| -
|| '''Bulbes'''
|-
|| 22001
|| -
|| Ail
|-
|| 22002
|| -
|| Oignons
|-
|| 23000
|| -
|| '''Légumes fruits'''
|-
|| 23101
|| -
|| Tomates
|-
|| 23102
|| -
|| Poivrons
|-
|| 23103
|| -
|| Aubergines
|-
|| 23201
|| -
|| Concombres
|-
|| 23203
|| -
|| Courgettes
|-
|| 23301
|| -
|| Melons
|-
|| 23302
|| -
|| Potirons
|-
|| 23303
|| -
|| Pastèques
|-
|| 23306
|| -
|| Chayote
|-
|| 24000
|| -
|| '''Brassicées'''
|-
|| 24101
|| -
|| Brocolis
|-
|| 24102
|| -
|| Choux fleurs
|-
|| 24202
|| -
|| Choux pommés
|-
|| 24301
|| -
|| Choux de Chine
|-
|| 25000
|| -
|| '''Légumes feuilles'''
|-
|| 25102
|| -
|| Laitue
|-
|| 25103
|| -
|| Chicorée
|-
|| 25201
|| -
|| Épinards
|-
|| 25203
|| -
|| Feuilles de bettes
|-
|| 25603
|| -
|| Céleri
|-
|| 27000
|| -
|| '''Légumes tiges'''
|-
|| 27001
|| -
|| Asperges
|-
|| 27005
|| -
|| Artichauts
|-
|}
{{AutoCat}}
e4kog1ivbbo86pu52vzkuy87d7ow6z1
Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations
2
74495
764353
634757
2026-04-22T08:54:23Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/202 -Sujets, Unités et Évaluations]] vers [[Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
634757
wikitext
text/x-wiki
#[[/Évaluations/]]
#[[/Unités/]]
#[[/Sujets/]]
{{AutoCat}}
6rk3jdb46n7csb12fugznfh4g9x46qk
Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Unités
2
74496
764355
634758
2026-04-22T08:54:23Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/202 -Sujets, Unités et Évaluations/Unités]] vers [[Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Unités]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
634758
wikitext
text/x-wiki
{|
|| '''Id-SCA'''
|| -
|| '''UNITÉS'''
|-
|| 111000
|| -
|| '''ESPACE'''
|-
|| 111.101
|| -
|| mm
|-
|| 111110
|| -
|| cm
|-
|| 111120
|| -
|| m
|-
|| 111.212
|| -
|| m2
|-
|| 111221
|| -
|| m2/ha
|-
|| 111222
|| -
|| plantes/m2
|-
|| 111.223
|| -
|| plantes/ha
|-
|| 111510
|| -
|| m3
|-
|| 111.520
|| -
|| m3/ha
|-
|| 112000
|| -
|| '''TEMPS'''
|-
|| 112300
|| -
|| heures
|-
|| 112400
|| -
|| jours
|-
|| 112500
|| -
|| semaines
|-
|| 112700
|| -
|| mois
|-
|| 112800
|| -
|| années
|-
|| 113000
|| -
|| '''MESSE'''
|-
|| 113100
|| -
|| gr
|-
|| 113.112
|| -
|| gr/ha
|-
|| 113.121
|| -
|| graines/gr
|-
|| 113.122
|| -
|| gr/1000 graines
|-
|| 113.131
|| -
|| mg/lt
|-
|| 113200
|| -
|| kg
|-
|| 113.211
|| -
|| kg/m2
|-
|| 113.410
|| -
|| tonne/ha
|-
|| 113.410
|| -
|| TONNES / HA.
|-
|| 113.611
|| -
|| kg/ha
|-
|| 114000
|| -
|| '''CLIMATIQUE'''
|-
|| 114.160
|| -
|| Cº
|-
|| 115000
|| -
|| '''POURCENTAGE'''
|-
|| 115.100
|| -
|| ppm
|-
|| 115.200
|| -
|| 0/00
|-
|| 115.300
|| -
|| %
|-
|| 116000
|| -
|| '''UNITÉS TECHNIQUES SPÉCIFIQUES'''
|-
|| 116.554
|| -
|| ue/ha
|-
|| 116.555
|| -
|| ue/tm
|-
|| 116.574
|| -
|| kcal
|-
|| 116.711
|| -
|| dS/m
|-
|| 116.721
|| -
|| pH
|-
|| 117.010
|| -
|| nº
|-
|| 117.011
|| -
|| nº/ha
|-
|}
{{AutoCat}}
cxnp38v6y4kxm7ejrr5lz4q5dlqpp2j
Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Évaluations
2
74497
764356
647567
2026-04-22T08:54:24Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/202 -Sujets, Unités et Évaluations/Évaluations]] vers [[Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Évaluations]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
647567
wikitext
text/x-wiki
{|
|| '''Id-SCA'''
|| -
|| '''ÉVALUATION'''
|-
|| 101.110
|| -
|| '''QUALITÉ - INTENSITÉ -Influence'''
|-
|| 101.111
|| -
|| TRÈS BON
|-
|| 101.112
|| -
|| BON, grand, long, grand, facile, INTENSE
|-
|| 101.113
|| -
|| RÉGULIER, MEDIA, MODÉRÉ
|-
|| 101.114
|| -
|| MALO, LOW, court, petit, DUR, RARE, LÉGER
|-
|| 101.115
|| -
|| VERY BAD, NULL, NO, PRICELESS
|-
|| 101.200
|| -
|| '''TOLÉRANCE - RÉSISTANCE'''
|-
|| 101.210
|| -
|| très tolérant
|-
|| 101.220
|| -
|| TOLÉRANTE, ADAPTABLE, RÉSISTANT
|-
|| 101.230
|| -
|| MOYENNE, MOYENNE, RÉGULIER, TOLÉRANT
|-
|| 101.240
|| -
|| SENSIBLE, LOW, LOW TOLÉRANCE
|-
|| 101.250
|| -
|| TOLÉRANCE ZÉRO
|-
|| 101.400
|| -
|| '''BESOIN - PRÉFÉRENCE'''
|-
|| 101.410
|| -
|| exigeant
|-
|| 101.420
|| -
|| EXIGEANT
|-
|| 101.430
|| -
|| PREFER
|-
|| 101.440
|| -
|| ADAPTATION RÉGULIER
|-
|| 101.450
|| -
|| PAS EXIGEANT
|-
|| 101.500
|| -
|| '''VITESSE'''
|-
|| 101.510
|| -
|| TRÈS RAPIDE
|-
|| 101.520
|| -
|| FAST
|-
|| 101.530
|| -
|| MODÉRÉ FAST
|-
|| 101.540
|| -
|| RÉGULIER, MEDIA, MODÉRÉ
|-
|| 101.550
|| -
|| MODÉRÉ LENTE
|-
|| 101.560
|| -
|| LENT
|-
|| 101.570
|| -
|| TRÈS LENT
|-
|}
{{AutoCat}}
au6p083xsku0lvhhhsd7dviy969yut4
Utilisateur:Agrodata/Agrodatabase/Version imprimable
2
74508
764392
634698
2026-04-22T08:54:29Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/Version imprimable]] vers [[Utilisateur:Agrodata/Agrodatabase/Version imprimable]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
634698
wikitext
text/x-wiki
{{imprimable}}
tqnwxo9j8ualh5dikp6cedpsb1i6zh3
Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Sujets
2
74511
764354
636477
2026-04-22T08:54:23Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/202 -Sujets, Unités et Évaluations/Sujets]] vers [[Utilisateur:Agrodata/Agrodatabase/202 -Sujets, Unités et Évaluations/Sujets]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
636477
wikitext
text/x-wiki
{|
|| '''Id-SCA'''
|| -
|| '''SUJETS'''
|-
|| 270.000
|| -
|| COMPOSITION ALIMENTAIRE
|-
|| 311.000
|| -
|| '''TEMPÉRATURE'''
|-
|| 311.100
|| -
|| TEMPÉRATURE SOL
|-
|| 311.200
|| -
|| TEMPÉRATURE DE L’AIR
|-
|| 312.000
|| -
|| '''LUMIÈRE'''
|-
|| 312.100
|| -
|| LUMINOSITÉ
|-
|| 312.200
|| -
|| PHOTOPÉRIODE
|-
|| 314.000
|| -
|| '''EAU-PLUIE'''
|-
|| 314.200
|| -
|| QUALITÉ DE L’EAU IRRIGATION
|-
|| 314.400
|| -
|| TOXICITÉ SPÉCIFIQUE-TOLERANCE
|-
|| 321.000
|| -
|| '''PROPRIÉTÉS PHYSIQUE DES SOLS'''
|-
|| 321.100
|| -
|| TEXTURE
|-
|| 321.300
|| -
|| STRUCTURE
|-
|| 321.500
|| -
|| PROFONDEUR DE SOL
|-
|| 322.000
|| -
|| '''EAU DU SOL'''
|-
|| 322.100
|| -
|| NIVEAU D'EAU
|-
|| 322.300
|| -
|| MOUVEMENT DE L’EAU
|-
|| 322.400
|| -
|| BILAN HYDRIQUE
|-
|| 324.000
|| -
|| '''PROPRIÉTÉS PHYSIQUES ET CHIMIQUES'''
|-
|| 324.300
|| -
|| RÉACTION du SUELO-pH
|-
|| 324.400
|| -
|| SOLS SALINS ET ALCALINS
|-
|| 325.000
|| -
|| LES MOYENS BIOLOGIQUES
|-
|| 325.200
|| -
|| '''MATIERE ORGANIQUE - HUMUS'''
|-
|| 327.000
|| -
|| ÉLÉMENTS NUTRITIFS
|-
|| 327.100
|| -
|| '''ÉLÉMENTS CHIMIQUES'''
|-
|| 327.300
|| -
|| FERTILITÉ
|-
|| 327.400
|| -
|| ANALYSE DU SOL
|-
|| 327.600
|| -
|| ANALYSE DE FEUILLE
|-
|| 328.100
|| -
|| EXTRACTIONS-SURFACE
|-
|| 328.300
|| -
|| EXTRACTIONS-PRQDUCTO
|-
|| 330.000
|| -
|| FERTILISATION
|-
|| 331.000
|| -
|| KG-UNIDAD engrais/HA
|-
|| 336.000
|| -
|| UNIT ENGRAIS -PRODUIT
|-
|| 339.500
|| -
|| DISTRIBUTION TEMPORAIRE
|-
|| 621.000
|| -
|| '''SEMIS-PLANTATION'''
|-
|| 621.100
|| -
|| CARACTÉRISTIQUES MATÉRIEL VÉGÉTAL
|-
|| 621.200
|| -
|| FACTEURS TEMPORAIRES SEMIS-PLANTATION
|-
|| 622.000
|| -
|| PÉPINIÈRES- BOUTURES ET PLANTES
|-
|| 623.100
|| -
|| MODE (SEMIS-PLANTATION)
|-
|| 623.200
|| -
|| DENSITÉ (SEMIS-PLANTATION)
|-
|| 623.300
|| -
|| PROFONDEUR-LARGEUR
|-
|| 623.400
|| -
|| DILUTION (SEMIS-PLANTATION)
|-
|| 623.500
|| -
|| TRANSPLANTATION
|-
|| 630.000
|| -
|| TRAVAIL
|-
|| 631.100
|| -
|| PRÉPARATION AU SOL
|-
|| 632.000
|| -
|| CULTURE-SARCLAGE
|-
|| 640.000
|| -
|| ENTREPRISE AGRICOLE
|-
|| 641.000
|| -
|| SERRAGE, DE TUTORAJE ET DE DÉFENSE
|-
|| 646.100
|| -
|| ÉLAGAGE DE FORMATION
|-
|| 660.000
|| -
|| TRAVAIL DE COLLECTE
|-
|| 661.000
|| -
|| DÉBUT DE COLLECTE
|-
|| 663.000
|| -
|| PRODUCTION
|-
|| 664.000
|| -
|| COLLECTE DES ASPECTS TEMPORELS
|-
|| 670.000
|| -
|| POST-RÉCOLTE-MARKETING
|-
|| 671.000
|| -
|| CLASSIFICATION DES PRODUITS
|-
|| 672.000
|| -
|| STOCKAGE-TRANSPORT
|-
|}
{{AutoCat}}
dcswy1jvvicdbycydnd7rj29ubwozdf
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données
2
74512
764357
636478
2026-04-22T08:54:24Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
636478
wikitext
text/x-wiki
LEGUMES
#[[/ Fraises /]]
Légumes tubercules
#[[/ Pommes de terre /]]
Légumes tubercules tropicaux
#[[/ Manioc /]]
#[[/ Patates douces /]]
#[[/ Ignames /]]
Légumes racines
#[[/ Carottes /]]
#[[/ Radis /]]
#[[/ Navets /]]
Légumes bulbes
#[[/ Ail /]]
#[[/ Oignons /]]
Légumes fruits
#[[/ Tomates /]]
#[[/ Poivrons /]]
#[[/ Aubergines /]]
#[[/ Concombres /]]
#[[/ Courgettes /]]
#[[/ Melons /]]
#[[/ Potirons /]]
#[[/ Pastèques /]]
#[[/ Chayote /]]
Brassicées
#[[/ Brocolis /]]
#[[/ Choux fleurs /]]
#[[/ Choux pommés /]]
#[[/ Choux de Chine /]]
Légumes feuilles
#[[/ Laitue /]]
#[[/ Chicorée /]]
#[[/ Épinards /]]
#[[/ Feuilles de bettes /]]
#[[/ Céleri /]]
Légumes tiges
#[[/ Asperges /]]
#[[/ Artichauts /]]
{{AutoCat}}
caa5yq5snyreus3jctwr4k9h4k5deax
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Fraises
2
74609
764373
637345
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Fraises]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Fraises]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637345
wikitext
text/x-wiki
{|
|| '''Fraises'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| ice plant
|| Cº
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| Frost flowers
|| Cº
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| développement végétatif
|| Cº
|| 22,0
|| 20-24
|| _____
|- _____
|| fructification minimum
|| Cº
|| 12,0
|| _____
|| _____
|- _____
|| fructification optimale
|| Cº
|| _____
|| 15-20
|| _____
|- _____
|| HEURES FROID
|| heures
|| _____
|| _____
|| PREFER
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| Minimum annuel-pluie
|| mm
|| 600,0
|| _____
|| _____
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| POROSITÉ-aéré
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| DRAINED
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| CARBONATE DE CALCIUM ACTIVE
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,5-6,5
|| _____
|- _____
|| dS/m affecte les cultures
|| dS/m
|| 1,0
|| _____
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| LES MOYENS BIOLOGIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| MATIERE ORGANIQUE - HUMUS
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| RELATION CARBONE/AZOTE (C/N)
|| _____
|| 10,0
|| _____
|| _____
|- _____
|| POURCENTAGE D’HUMUS
|| %
|| 2,5
|| _____
|| _____
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| FERTILITÉ
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 190,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 125,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 230,0
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 8,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 9,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 85.000,0
|| 70,000-100,000
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| _____
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| _____
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| _____
|| 85-90
|| _____
|- _____
|| TEMPS STOCKAGE AU FROID
|| jours
|| 6,0
|| 3-10
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 91,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 9,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 32,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 355,6
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 7,7
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 85,6
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 4,9
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 54,4
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,0
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 22,2
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,3
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 3,3
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 0,7
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 7,8
|| _____
|| _____
|- _____
|}
{{AutoCat}}
ce7a4n754mzip9b8www8y71rztglq8s
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Pommes de terre
2
74615
764383
637350
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Pommes de terre]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Pommes de terre]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637350
wikitext
text/x-wiki
{|
|| '''Pommes de terre'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| BUDDING - minimum planting
|| Cº
|| 7,0
|| _____
|| _____
|- _____
|| TUBERIZATION - OPTIMA
|| Cº
|| 18,0
|| _____
|| _____
|- _____
|| frozen tuber
|| Cº
|| _____
|| -1 a -2
|| _____
|- _____
|| ice plant
|| Cº
|| _____
|| -3 / - 4
|| _____
|- _____
|| Air - minimum growth zero temperature vegetation
|| Cº
|| _____
|| 5-7
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 14-18
|| _____
|- _____
|| LUMIÈRE
|| _____
|| _____
|| _____
|| _____
|- _____
|| JOUR COURT
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| MM. CYCLE PLANT
|| mm
|| 600,0
|| 500-750
|| _____
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 2,5-1,25
|| MODÉRÉMENT
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| POROSITÉ-aéré
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| sols profonds
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| HUMIDES
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| GORGÉS D’EAU
|| _____
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| REACTION SOL-pH
|| _____
|| _____
|| neutro
|| _____
|- _____
|| pH 5, 5-6
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| pH 6-6, 5
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| PH MINIMUM
|| pH
|| _____
|| 5,5-6
|| _____
|- _____
|| dS/m affecte les cultures
|| dS/m
|| 1,7
|| _____
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| ZINC-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| MANGANÈSE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| CUIVRE-DÉFICIENCES
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| MOLYBDÈNE-DÉFICIENCES
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| BORE-DÉFICIENCES
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 22,5
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 125,0
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 4,0
|| 3-5
|| _____
|- _____
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,9
|| 0,8-1
|| _____
|- _____
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 5,0
|| 4-6
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 70,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 120,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 72,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 85,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 130,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 170,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 210,0
|| _____
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,8
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,8
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 4,8
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,4
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,9
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,4
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 5,2
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 6,8
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 8,4
|| _____
|| _____
|- _____
|| AZOTE-PRÉSEMIS
|| %
|| _____
|| 1/2
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| _____
|| 50 % tuberizacion
|| _____
|- _____
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-PRÉSEMIS
|| %
|| _____
|| 1/2
|| _____
|- _____
|| POTASSIUM-SEMIS
|| %
|| 50,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| POIDS MOYEN, GR
|| gr
|| 30,0
|| _____
|| _____
|- _____
|| Jours de plantation puis hachés
|| jours
|| _____
|| 1-2
|| _____
|- _____
|| TROPIQUES, pépinières de hauteur minimale
|| m
|| 1.200,0
|| _____
|| _____
|- _____
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 1.900,0
|| 1.200-2.500
|| _____
|- _____
|| CRÊTES, DISTANCE loin
|| cm
|| 75,0
|| 70-80
|| _____
|- _____
|| CRÊTES, DISTANCE PLANTES
|| cm
|| 25,0
|| _____
|| _____
|- _____
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 47.000,0
|| 40.000-55.000
|| _____
|- _____
|| TUBERCULES profondeur
|| cm
|| _____
|| 7-8
|| _____
|- _____
|| TRAVAIL
|| _____
|| _____
|| _____
|| _____
|- _____
|| labourant PROFONDEUR
|| cm
|| 25,0
|| _____
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| 20-30
|| _____
|- _____
|| Hauteur destruction PLANT
|| cm
|| 17,0
|| 15-20
|| _____
|- _____
|| Semaines APRES destruction végétation
|| semaines
|| 2,0
|| _____
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 20,0
|| _____
|| _____
|- _____
|| Température de stockage pour les semis
|| Cº
|| _____
|| 2-4
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| _____
|| 85-90
|| _____
|- _____
|| TEMPS STOCKAGE MAXIMUM
|| mois
|| _____
|| varios meses
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 75,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 25,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 77,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 308,0
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 17,5
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 70,0
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 0,8
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 6,7
|| _____
|| _____
|- _____
|| AMIDON-Produits frais
|| gr
|| 15,5
|| _____
|| _____
|- _____
|| AMIDON-matière sec
|| %
|| 62,0
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,2
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 8,8
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,4
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 2,0
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 8,0
|| _____
|| _____
|- _____
|}
{{AutoCat}}
mtbuw7xucevgt7siobeqrj5ljfpdvct
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Manioc
2
74616
764376
637347
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Manioc]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Manioc]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637347
wikitext
text/x-wiki
{|
|| '''Manioc'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| ice plant
|| Cº
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 20,0
|| _____
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 25-29
|| _____
|- _____
|| LUMIÈRE
|| _____
|| _____
|| _____
|| _____
|- _____
|| JOUR COURT
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| Minimum annuel-pluie
|| mm
|| 500,0
|| _____
|| _____
|- _____
|| MM. CYCLE PLANT
|| mm
|| 1.350,0
|| 1.200-1.500
|| _____
|- _____
|| RÉSISTANCE À LA SÉCHERESSE
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| sols profonds
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| GORGÉS D’EAU
|| _____
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| TRÈS TOLÉRANT
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,8-6,5
|| _____
|- _____
|| dS/m maximum
|| dS/m
|| 0,5
|| _____
|| _____
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 75,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 25,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,5
|| 2-3
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 80,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 90,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 40,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 80,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 90,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 105,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| _____
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 5,3
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 6,7
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,7
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 5,3
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 7,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 8,0
|| _____
|| _____
|- _____
|| AZOTE-PRÉSEMIS
|| %
|| _____
|| 1/3
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| _____
|| 1/3 un mes
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT PLANT-2ème aportación
|| %
|| _____
|| 1/3 dos meses
|| _____
|- _____
|| PHOSPHORE-SEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-SEMIS
|| _____
|| _____
|| 1/3
|| _____
|- _____
|| POTASSIUM- DÉVELOPPEMENT PLANT 1ème contribution
|| _____
|| _____
|| 1/3 un mes
|| _____
|- _____
|| POTASSIUM- DÉVELOPPEMENT PLANT 2ème contribution
|| _____
|| _____
|| 1/3 dos meses
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| Nº JAUNES de BOUTURES-tubercule Nº
|| nº
|| _____
|| 3-4
|| _____
|- _____
|| Âge BOUTURES
|| mois
|| 13,0
|| 8-18
|| _____
|- _____
|| % pieu-BOUTURES ENTERRÉ
|| %
|| _____
|| 2/3
|| _____
|- _____
|| HAUTEUR pieu-BOUTURES
|| cm
|| 20,0
|| 10-30
|| _____
|- _____
|| largeur de lignes.
|| m
|| 1,3
|| 1,2-1,5
|| _____
|- _____
|| LARGEUR ENTRE PLANTES M.
|| m
|| 0,8
|| _____
|| _____
|- _____
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 10.000,0
|| 8.000-12.000
|| _____
|- _____
|| TRAVAIL
|| _____
|| _____
|| _____
|| _____
|- _____
|| N ° - DÉSHERBAGE
|| nº
|| _____
|| 2-3
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 15,0
|| _____
|| _____
|- _____
|| Poids moyen
|| gr
|| 600,0
|| 400-800
|| _____
|- _____
|| cycle récolte
|| mois
|| 11,0
|| 10-12
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 60,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 40,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 160,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 400,0
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 38,0
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 95,0
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 1,7
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 4,3
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,8
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 4,5
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,3
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,7
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 1,4
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 3,5
|| _____
|| _____
|- _____
|}
{{AutoCat}}
md3q669iyn2unpix5eot7hf2uyuamhs
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Patates douces
2
74617
764381
637349
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Patates douces]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Patates douces]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637349
wikitext
text/x-wiki
{|
|| '''Patates douces'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| SOIL TEMPERATURE
|| Cº
|| _____
|| 15-18
|| _____
|- _____
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 12,0
|| _____
|| _____
|- _____
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 15,0
|| _____
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 22-30
|| _____
|- _____
|| TEMPERATURE AIR - maximale
|| Cº
|| 30,0
|| _____
|| _____
|- _____
|| HAUTEUR M. (FROID EN TROPIQUES) maxime
|| m
|| 1.200,0
|| _____
|| _____
|- _____
|| LUMIÈRE
|| _____
|| _____
|| _____
|| _____
|- _____
|| JOUR COURT
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| Minimum annuel-pluie
|| mm
|| 850,0
|| 750-1000
|| _____
|- _____
|| pluie - semaine
|| mm
|| 2,5
|| _____
|| _____
|- _____
|| HUMIDITE AIR % RH
|| %
|| _____
|| 80-85
|| _____
|- _____
|| RÉSISTANCE À LA SÉCHERESSE
|| semaines
|| 3,0
|| _____
|| _____
|- _____
|| PÉRIODES SÈCHES-COMMODITÉ
|| semaines
|| _____
|| 2-3 semanas antes recoleccion
|| _____
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 0,75-1,0
|| SENSIBLE
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| LOURDS - ARGILE
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| profondeur moyenne
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| DRAINED
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| ENGORGEMENT, TOLÉRANCE
|| _____
|| _____
|| _____
|| NE TOLÈRE PAS
|- _____
|| SECHERESSE-TOLERANCE
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,5-6,5
|| _____
|- _____
|| dS/m maximum
|| dS/m
|| _____
|| 1,5 a 2,5
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 70,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 15,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 4,5
|| 4-5
|| _____
|- _____
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,0
|| 0,8-1,2
|| _____
|- _____
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 6,7
|| 6,5-7
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 35,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 47,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 50,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 90,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 130,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 170,0
|| _____
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,3
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,1
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 6,7
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 8,7
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 11,3
|| _____
|| _____
|- _____
|| AZOTE-SEMIS
|| %
|| _____
|| 2/3
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| _____
|| 1/3 - 40 dias
|| _____
|- _____
|| PHOSPHORE-SEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-SEMIS
|| _____
|| _____
|| 1/2
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| Tuber diamètre CM.
|| cm
|| 4,0
|| _____
|| _____
|- _____
|| DENSITÉ, PLANTE/REPOUSSE/TUBERCULES-m2
|| plantes/m2
|| 1.500,0
|| _____
|| _____
|- _____
|| tubercules-kg/m2
|| kg/m2
|| 10,0
|| _____
|| _____
|- _____
|| TRANSPLANTATION, LONGUEUR FEUILLES No.
|| nº
|| _____
|| 6-10
|| _____
|- _____
|| TRANSPLANTATION AGE PLANTE mois
|| mois
|| _____
|| 2-3
|| _____
|- _____
|| HAUTEUR pieu-BOUTURES
|| cm
|| 30,0
|| _____
|| _____
|- _____
|| LARGEUR ENTRE PLANTES M.
|| m
|| 0,3
|| _____
|| _____
|- _____
|| CRÊTES, DISTANCE loin
|| m
|| 1,0
|| 0,75-1,3
|| _____
|- _____
|| CRÊTES, loin HAUTEUR
|| cm
|| 22,0
|| 20-25
|| _____
|- _____
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 30.000,0
|| _____
|| _____
|- _____
|| CRÊTES ou tables largeur
|| cm
|| _____
|| 40-45
|| _____
|- _____
|| TUBERCULES profondeur
|| cm
|| 5,0
|| _____
|| _____
|- _____
|| TRAVAIL
|| _____
|| _____
|| _____
|| _____
|- _____
|| labourant PROFONDEUR
|| cm
|| 25,0
|| _____
|| _____
|- _____
|| 1er désherbage , moment APRÈS plantation
|| jours
|| 45,0
|| 40-50
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| début récolter ÂGE PLANTE
|| mois
|| _____
|| 4-6
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 15,0
|| 10-20
|| _____
|- _____
|| cycle récolte
|| mois
|| 4,5
|| 3,5-6
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| _____
|| 13-16
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| _____
|| 85-90
|| _____
|- _____
|| TEMPS STOCKAGE MAXIMUM
|| mois
|| 1,0
|| _____
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 77,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 23,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 86,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 373,9
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 20,1
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 87,4
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 4,2
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 18,3
|| _____
|| _____
|- _____
|| AMIDON-Produits frais
|| gr
|| 12,7
|| _____
|| _____
|- _____
|| AMIDON-matière sec
|| %
|| 55,2
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 3,0
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 13,0
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,4
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 1,6
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 7,0
|| _____
|| _____
|- _____
|}
{{AutoCat}}
o95k7gtaeia32n3d1txakpppbicpz8i
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Ignames
2
74618
764374
647561
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Ignames]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Ignames]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
647561
wikitext
text/x-wiki
{|
|| '''Ignames'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE AIR - optimale culture
|| ºC
|| _____
|| 23 a 25
|| _____
|- _____
|| LUMIÈRE
|| _____
|| _____
|| _____
|| _____
|- _____
|| JOUR COURT
|| _____
|| _____
|| _____
|| PRÉFÈRE
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| Minimum annuel-pluie
|| mm
|| 1.000,0
|| _____
|| _____
|- _____
|| EAU - QUANTITÉ
|| mm
|| _____
|| 400 mm de 3º a 5º mes
|| _____
|- _____
|| MM. CYCLE PLANT
|| mm
|| 1.500,0
|| _____
|| _____
|- _____
|| DÉFICIT DE L'EAU-PÉRIODES CRITIQUES
|| _____
|| _____
|| 5 primeros meses
|| _____
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PRÉFÈRE
|- _____
|| sols profonds
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| DRAINED
|| _____
|| _____
|| _____
|| TRÈS EXIGEANT
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 6 a 7
|| _____
|- _____
|| MATIÈRE ORGANIQUE - HUMUS
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| FERTILITÉ
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| POTASSIUM- SOL
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| POIDS MOYEN, GR
|| gr
|| 130,0
|| 120-140
|| _____
|- _____
|| Nº JAUNES de BOUTURES-tubercule Nº
|| nº
|| _____
|| 2-3
|| _____
|- _____
|| PÉRIODE RESTE
|| mois
|| _____
|| 3-6
|| _____
|- _____
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| _____
|| 20-60
|| _____
|- _____
|| CRÊTES, DISTANCE loin
|| m
|| 1,2
|| 1-1,5
|| _____
|- _____
|| CRÊTES, DISTANCE PLANTES
|| cm
|| 60,0
|| 50-70
|| _____
|- _____
|| TUBERCULES profondeur
|| cm
|| _____
|| 5-7
|| _____
|- _____
|| TRAVAIL
|| _____
|| _____
|| _____
|| _____
|- _____
|| N ° - DÉSHERBAGE
|| nº
|| 3,0
|| _____
|| _____
|- _____
|| ENTREPRISE AGRICOLE
|| _____
|| _____
|| _____
|| _____
|- _____
|| FIXATION, tutoraje ET DÉFENSE
|| _____
|| _____
|| _____
|| TRÈS EXIGEANT
|- _____
|| HAUTEUR sol tuteur
|| m
|| 3,0
|| _____
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| début récolter ÂGE PLANTE
|| mois
|| _____
|| 9-10
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 10,0
|| _____
|| _____
|- _____
|| Poids moyen
|| kg
|| 3,5
|| 2 a 5
|| _____
|- _____
|| TEMPS DURÉE récolter
|| mois
|| _____
|| 2-3
|| _____
|- _____
|| cycle récolte
|| mois
|| 7,0
|| _____
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| ºC
|| 7,0
|| _____
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 70,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 30,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 118,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 393,3
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 28,0
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 93,3
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 0,5
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 1,7
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 4,1
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 13,7
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,6
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 1,5
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 5,0
|| _____
|| _____
|- _____
|}
{{AutoCat}}
iytjdw9jcmcdntm8dme0zhfjrk3frlg
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Carottes
2
74619
764363
637344
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Carottes]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Carottes]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637344
wikitext
text/x-wiki
{|
|| '''Carottes'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| GERMINATION - MINIMUM
|| Cº
|| 5,0
|| _____
|| _____
|- _____
|| GERMINATION - OPTIMA
|| Cº
|| _____
|| 7-29
|| _____
|- _____
|| frozen tuber
|| Cº
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 7,0
|| _____
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 25-27
|| _____
|- _____
|| TEMPERATURE AIR - maximale
|| Cº
|| 28,0
|| _____
|| _____
|- _____
|| développement végétatif
|| Cº
|| _____
|| 15-18
|| _____
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| MM. CYCLE PLANT
|| mm
|| 500,0
|| _____
|| _____
|- _____
|| DÉFICIT EN EAU
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 3,75-2,5
|| TOLÉRANTE
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| LOURDS - ARGILE
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| francs légers
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,5 a 6,8
|| _____
|- _____
|| dS/m affecte les cultures
|| dS/m
|| 1,0
|| _____
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| TOLÉRANCE PLANTES alcalinité du sol
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| MATIERE ORGANIQUE - HUMUS
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| POTASSIUM
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| AZOTE-feuille-assez
|| 0/00
|| 10,0
|| _____
|| _____
|- _____
|| AZOTE-feuille-intermédiaire
|| 0/00
|| 7,5
|| _____
|| _____
|- _____
|| azote Feuille-PAUVRE
|| 0/00
|| 5,0
|| _____
|| _____
|- _____
|| PHOSPHORE-feuille-assez
|| 0/00
|| 4,0
|| _____
|| _____
|- _____
|| PHOSPHORE-feuille-intermédiaire
|| 0/00
|| 3,0
|| _____
|| _____
|- _____
|| PHOSPHORE Feuille-PAUVRE
|| 0/00
|| 2,0
|| _____
|| _____
|- _____
|| POTASSIUM-feuille-assez
|| %
|| 6,0
|| _____
|| _____
|- _____
|| POTASSIUM-feuille-intermédiaire
|| %
|| 5,0
|| _____
|| _____
|- _____
|| POTASSIUM Feuille-PAUVRE
|| %
|| 4,0
|| _____
|| _____
|- _____
|| ZINC-DÉFICIENCES
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| CUIVRE-DÉFICIENCES
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| MOLYBDÈNE-DÉFICIENCES
|| _____
|| _____
|| _____
|| TOLÉRANTE
|- _____
|| BORE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 125,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 50,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 150,0
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 4,5
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,8
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 5,5
|| _____
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 80,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 120,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 150,0
|| _____
|| _____
|- _____
|| Fumier / Ha
|| tonne/ha
|| 20,0
|| 15-20
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,7
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,5
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| _____
|| 3-5
|| _____
|- _____
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 0,8
|| _____
|| _____
|- _____
|| GRAINES ans capacité germinative
|| années
|| 3,0
|| _____
|| _____
|- _____
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 3,2
|| 2,5-4
|| _____
|- _____
|| RETIRER, distance entre plantes
|| cm
|| 15,0
|| _____
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| début récolter ÂGE PLANTE
|| mois
|| _____
|| 3-4
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| 25-30
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| _____
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| _____
|| 90-95
|| _____
|- _____
|| TEMPS STOCKAGE AU FROID
|| mois
|| _____
|| 2-3
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 88,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 12,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 41,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 341,7
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 9,6
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 80,0
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 0,8
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 6,7
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,8
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 23,3
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,0
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 0,9
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 7,8
|| _____
|| _____
|- _____
|}
{{AutoCat}}
pad9z5eze2g2m7jjqcljkjk3fxvcv6e
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Radis
2
74620
764385
637351
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Radis]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Radis]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637351
wikitext
text/x-wiki
{|
|| '''Radis'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| GERMINATION - OPTIMA
|| Cº
|| 22,0
|| 20-25
|| _____
|- _____
|| frozen tuber
|| Cº
|| _____
|| -2
|| _____
|- _____
|| développement végétatif
|| Cº
|| _____
|| 15-18
|| _____
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 2,5-1,25
|| MODÉRÉMENT
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,5-6,8
|| _____
|- _____
|| dS/m affecte les cultures
|| dS/m
|| 1,2
|| _____
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| MANGANÈSE-DÉFICIENCES
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| CUIVRE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| MOLYBDÈNE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| BORE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 50,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 75,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 30,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 45,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 80,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,5
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,8
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 1,5
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,3
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,5
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| AZOTE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 10,5
|| _____
|| _____
|- _____
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| _____
|| _____
|- _____
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| _____
|| 2-3
|| _____
|- _____
|| GROOVE, LIGNES DE DISTANCE
|| cm
|| 20,0
|| 15-25
|| _____
|- _____
|| TABLE, DISTANCE ENTRE LES PLANTES
|| cm
|| 7,0
|| 5-10
|| _____
|- _____
|| Tableau n ° - LIGNES
|| nº
|| 5,0
|| 4-6
|| _____
|- _____
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 8,0
|| _____
|| _____
|- _____
|| RETIRER, distance entre plantes
|| cm
|| 10,0
|| _____
|| _____
|- _____
|| RETIRER, JOURS DEPUIS REPOUSSE
|| jours
|| 17,0
|| 15-20
|| _____
|- _____
|| TRAVAIL
|| _____
|| _____
|| _____
|| _____
|- _____
|| N ° - DÉSHERBAGE
|| nº
|| _____
|| 1-2
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| début récolter ÂGE PLANTE
|| mois
|| _____
|| 1-1,5
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 20,0
|| _____
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| _____
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| _____
|| 90-95
|| _____
|- _____
|| TEMPS STOCKAGE AU FROID
|| mois
|| _____
|| 3-4
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 88,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 12,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 4,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 33,3
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,4
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 28,3
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 1,9
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 15,8
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,6
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 13,3
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,8
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 0,7
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 5,8
|| _____
|| _____
|- _____
|}
{{AutoCat}}
3pn34989e73ys2bfcmb3a7m9ab7hiwk
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Navets
2
74623
764378
637348
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Navets]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Navets]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
637348
wikitext
text/x-wiki
{|
|| '''Navets'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| GERMINATION - MINIMUM
|| Cº
|| 2,0
|| _____
|| _____
|- _____
|| GERMINATION - OPTIMA
|| Cº
|| _____
|| 15-35
|| _____
|- _____
|| Air - minimum growth zero temperature vegetation
|| Cº
|| _____
|| 4-5
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 15-18
|| _____
|- _____
|| TEMPERATURE AIR - maximale
|| Cº
|| 25,0
|| _____
|| _____
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 3,75-2,5
|| TOLÉRANTE
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| LOURDS - ARGILE
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| GAMME OPTIMUM pH
|| pH
|| _____
|| 5,5-6,8
|| _____
|- _____
|| dS/m affecte les cultures
|| dS/m
|| 0,9
|| _____
|| _____
|- _____
|| TOLÉRANCE PLANTES salinité du sol
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| MANGANÈSE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| CUIVRE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| MOLYBDÈNE-DÉFICIENCES
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| BORE-DÉFICIENCES
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 115,0
|| _____
|| _____
|- _____
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 125,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 70,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 80,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 130,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 160,0
|| _____
|| _____
|- _____
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,5
|| _____
|| _____
|- _____
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,4
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,8
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,2
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 5,2
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 6,4
|| _____
|| _____
|- _____
|| AZOTE-PRÉSEMIS
|| %
|| _____
|| 2/3
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| _____
|| 1/3
|| _____
|- _____
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 3,8
|| 3,3-4,3
|| _____
|- _____
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| _____
|| _____
|- _____
|| GROOVE, LIGNES DE DISTANCE
|| cm
|| 37,0
|| 35-40
|| _____
|- _____
|| GROOVE, PLANTE DISTANCE cm
|| cm
|| 20,0
|| 10-30
|| _____
|- _____
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 6,0
|| 4-8
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| début récolter ÂGE PLANTE
|| mois
|| _____
|| 2-2,5
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| 20-30
|| _____
|- _____
|| POST-RÉCOLTE-MARKETING
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| _____
|| _____
|- _____
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| _____
|| _____
|- _____
|| TEMPS STOCKAGE AU FROID
|| mois
|| 3,0
|| _____
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 93,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 7,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 20,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 285,7
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 4,4
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 62,9
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 0,5
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 7,1
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 3,5
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 50,0
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,9
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 1,1
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 15,7
|| _____
|| _____
|- _____
|}
{|
|| '''Ail'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|- _____
|| '''CLIMAT'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| TEMPÉRATURE
|| _____
|| _____
|| _____
|| _____
|- _____
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 0,0
|| _____
|| _____
|- _____
|| TEMPERATURE AIR - optimale culture
|| Cº
|| _____
|| 8-20
|| _____
|- _____
|| Tª nuit optimale
|| Cº
|| 16,0
|| _____
|| _____
|- _____
|| développement végétatif
|| Cº
|| _____
|| 18-20
|| _____
|- _____
|| HAUTEUR M. (FROID EN TROPIQUES) optimale
|| m
|| 900,0
|| _____
|| _____
|- _____
|| LUMIÈRE
|| _____
|| _____
|| _____
|| _____
|- _____
|| JOUR LONG
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| EAU
|| _____
|| _____
|| _____
|| _____
|- _____
|| BORe-EAU IRRIGATION
|| mg/lt
|| _____
|| 0,75-1,0
|| SENSIBLE
|- _____
|| '''SOL'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| _____
|| _____
|| _____
|| _____
|- _____
|| DEMIE - FRANK
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| ARGILE
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| SANDY
|| _____
|| _____
|| _____
|| SENSIBLE
|- _____
|| EAU DU SOL
|| _____
|| _____
|| _____
|| _____
|- _____
|| DRAINED
|| _____
|| _____
|| _____
|| EXIGEANT
|- _____
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| _____
|| _____
|| _____
|| _____
|- _____
|| USINE de tolérance au pH acide
|| _____
|| _____
|| _____
|| MODÉRÉMENT
|- _____
|| ÉLÉMENTS NUTRITIFS
|| _____
|| _____
|| _____
|| _____
|- _____
|| POTASSIUM
|| _____
|| _____
|| _____
|| PREFER
|- _____
|| '''FERTILISATION'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 150,0
|| 150
|| _____
|- _____
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 47,0
|| 35-60
|| _____
|- _____
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 175,0
|| 150-200
|| _____
|- _____
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 21,0
|| _____
|| _____
|- _____
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 7,0
|| _____
|| _____
|- _____
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 25,0
|| _____
|| _____
|- _____
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 40,0
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 50,0
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 50,0
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| _____
|| _____
|- _____
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| _____
|| _____
|- _____
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 14,3
|| _____
|| _____
|- _____
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 5,7
|| _____
|| _____
|- _____
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 7,1
|| _____
|| _____
|- _____
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 8,6
|| _____
|| _____
|- _____
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 7,1
|| _____
|| _____
|- _____
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 10,7
|| _____
|| _____
|- _____
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 14,3
|| _____
|| _____
|- _____
|| AZOTE-PRÉSEMIS
|| %
|| _____
|| 1/2
|| _____
|- _____
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| _____
|| 1/2
|| _____
|- _____
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| _____
|| _____
|- _____
|| '''TECHNIQUES DE CULTURE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| SEMIS-PLANTATION
|| _____
|| _____
|| _____
|| _____
|- _____
|| CRÊTES, n ° LIGNES
|| nº
|| 2,0
|| _____
|| _____
|- _____
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 700,0
|| _____
|| _____
|- _____
|| CRÊTES, DISTANCE loin
|| cm
|| 50,0
|| _____
|| _____
|- _____
|| CRÊTES, DISTANCE PLANTES
|| cm
|| 20,0
|| _____
|| _____
|- _____
|| GRAINES PROFONDEUR
|| cm
|| _____
|| 2-3
|| _____
|- _____
|| TRAVAIL DE COLLECTE
|| _____
|| _____
|| _____
|| _____
|- _____
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 7,0
|| _____
|| _____
|- _____
|| cycle récolte
|| mois
|| _____
|| 4-5,5
|| _____
|- _____
|| '''COMPOSITION ALIMENTAIRE'''
|| _____
|| _____
|| _____
|| _____
|- _____
|| Eau -Produit Frais
|| gr
|| 60,0
|| _____
|| _____
|- _____
|| matière sèche - produit Frais
|| gr
|| 40,0
|| _____
|| _____
|- _____
|| Énergie-produits frais
|| kcal
|| 149,0
|| _____
|| _____
|- _____
|| Énergie-matière sec
|| kcal
|| 372,5
|| _____
|| _____
|- _____
|| Hydrates de carbone-Producto Frais
|| gr
|| 33,0
|| _____
|| _____
|- _____
|| Hydrates de carbone-matière sec
|| %
|| 82,5
|| _____
|| _____
|- _____
|| SUCRE-produits frais
|| gr
|| 1,0
|| _____
|| _____
|- _____
|| SUCRE-matière sec
|| %
|| 2,5
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,1
|| _____
|| _____
|- _____
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 5,3
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,5
|| _____
|| _____
|- _____
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,3
|| _____
|| _____
|- _____
|| protéines-Produits frais
|| gr
|| 6,4
|| _____
|| _____
|- _____
|| protéines- matière sec
|| %
|| 16,0
|| _____
|| _____
|- _____
|}
{{AutoCat}}
g7ux2k0ou160qxiuxv4s809x9tliz1b
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Ail
2
74704
764358
638471
2026-04-22T08:54:24Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Ail]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Ail]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638471
wikitext
text/x-wiki
{|
|| '''Ail'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 0,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 8-20
|| ______
|-
|| Tª nuit optimale
|| Cº
|| 16,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 18-20
|| ______
|-
|| HAUTEUR M. (FROID EN TROPIQUES) optimale
|| m
|| 900,0
|| ______
|| ______
|-
|| LUMIÈRE
|| ______
|| ______
|| ______
|| ______
|-
|| JOUR LONG
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 0,75-1,0
|| SENSIBLE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| ARGILE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| SANDY
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| POTASSIUM
|| ______
|| ______
|| ______
|| PREFER
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 150,0
|| 150
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 47,0
|| 35-60
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 175,0
|| 150-200
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 21,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 7,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 25,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 50,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 50,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 14,3
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 5,7
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 7,1
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 8,6
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 7,1
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 10,7
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 14,3
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| CRÊTES, n ° LIGNES
|| nº
|| 2,0
|| ______
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 700,0
|| ______
|| ______
|-
|| CRÊTES, DISTANCE loin
|| cm
|| 50,0
|| ______
|| ______
|-
|| CRÊTES, DISTANCE PLANTES
|| cm
|| 20,0
|| ______
|| ______
|-
|| GRAINES PROFONDEUR
|| cm
|| ______
|| 2-3
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 7,0
|| ______
|| ______
|-
|| cycle récolte
|| mois
|| ______
|| 4-5,5
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 60,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 40,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 149,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 372,5
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 33,0
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 82,5
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,0
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 2,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,1
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 5,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,5
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 6,4
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 16,0
|| ______
|| ______
|-
|}
{{AutoCat}}
cszx64e585j01xsar7hwbv9u8tpd60b
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Oignons
2
74705
764379
638487
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Oignons]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Oignons]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638487
wikitext
text/x-wiki
{|
|| '''Oignons'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 5,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 12-24
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 29,0
|| ______
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| 2,0
|| ______
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| 24,0
|| ______
|| ______
|-
|| LUMIÈRE
|| ______
|| ______
|| ______
|| ______
|-
|| JOUR LONG
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| Conductivité électrique-CE-dS / m
|| dS/m
|| 1,2
|| ______
|| ______
|-
|| SODIUM-EAU IRRIGATION
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 3,75-2,5
|| TOLÉRANTE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DEGRÉ DE SATURATION %
|| %
|| 60,0
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6-6,8
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,2
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| ZINC-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,9
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,5
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS-N-haute (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS-N-moyenne (UF Kg / Ha)
|| ue/ha
|| 185,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 220,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 130,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,7
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 8,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,2
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 4,4
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 2,2
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,7
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 7,3
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 2/5
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 3/5
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 3,6
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 250,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 1,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| 10,0
|| ______
|| ______
|-
|| DENSITÉ, PLANTE/REPOUSSE/TUBERCULES-m2
|| plantes/m2
|| 1.750,0
|| 1.500-2.000
|| ______
|-
|| PÉPINIÈRE m2 / HA CULTIVÉ
|| m2/ha
|| 400,0
|| 300-500
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 3.000,0
|| ______
|| ______
|-
|| PROFONDEUR CM.
|| cm
|| 0,5
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| 45,0
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| cm
|| 17,0
|| 15-20
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 8,0
|| 6-10(semillas)-700(bulbillos)
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 260.000,0
|| 220.000-300.000
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE-long, froid
|| mois
|| 8,0
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE-court, chaud
|| mois
|| 4,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 27,0
|| 25-30
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 89,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 11,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 40,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 363,6
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 9,3
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 84,5
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 4,2
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 38,2
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 15,5
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 0,9
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,1
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 10,0
|| ______
|| ______
|-
|}
{{AutoCat}}
kdgxdg9cyyn5nvz1v2heb70fo6iprw5
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Tomates
2
74706
764386
638491
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Tomates]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Tomates]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638491
wikitext
text/x-wiki
{|
|| '''Tomates'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - OPTIMA
|| Cº
|| 19,0
|| 18-20
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| ______
|| 10-11
|| ______
|-
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 0,0
|| ______
|| ______
|-
|| Tª diurne optimale
|| Cº
|| ______
|| ______
|| ______
|-
|| Tª nuit optimale
|| Cº
|| ______
|| ______
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 32,0
|| ______
|| ______
|-
|| développement végétatif-en journée
|| Cº
|| ______
|| 18-20
|| ______
|-
|| développement végétatif-nuit
|| Cº
|| 15,0
|| ______
|| ______
|-
|| fleur-en journée
|| Cº
|| ______
|| 22-23
|| ______
|-
|| Fleur-nuit
|| Cº
|| ______
|| 13-17
|| ______
|-
|| fructification en journée
|| Cº
|| 25,0
|| ______
|| ______
|-
|| fructification nuit
|| Cº
|| 18,0
|| ______
|| ______
|-
|| INTEGRAL THERMIQUE
|| Cº
|| ______
|| 3.000-4.000
|| ______
|-
|| LUMIÈRE
|| ______
|| ______
|| ______
|| ______
|-
|| BESOIN DE LUMIÈRE
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PHOTOPÉRIODE touché
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| HUMIDITE AIR % RH
|| %
|| ______
|| 60-80
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 2,5-1,25
|| MODÉRÉMENT
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| PREFER
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| 5,5
|| ______
|| ______
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6,5-6,8
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 2,5
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| AZOTE-feuille-assez
|| ppm
|| 5.000,0
|| ______
|| ______
|-
|| azote Feuille-PAUVRE
|| ppm
|| 2.000,0
|| ______
|| ______
|-
|| PHOSPHORE-feuille-assez
|| ppm
|| 3.000,0
|| ______
|| ______
|-
|| PHOSPHORE Feuille-PAUVRE
|| ppm
|| 1.500,0
|| ______
|| ______
|-
|| POTASSIUM-feuille-assez
|| %
|| 3,0
|| ______
|| ______
|-
|| POTASSIUM Feuille-PAUVRE
|| %
|| 1,5
|| ______
|| ______
|-
|| ZINC-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 25,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,6
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,8
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 180,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 190,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 160,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 240,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,8
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 2,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 3-5
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 4,5
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 350,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 3,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 6-8
|| ______
|-
|| PÉPINIÈRE m2 / HA CULTIVÉ
|| m2/ha
|| ______
|| 100-500
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 300,0
|| ______
|| ______
|-
|| PROFONDEUR CM.
|| cm
|| 0,5
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 25-30
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 17.000,0
|| 15.000-20.000
|| ______
|-
|| PLANTATION distance lignes
|| m
|| 0,9
|| 0,80-1,00
|| ______
|-
|| plantation distance plantes
|| m
|| 0,5
|| ______
|| ______
|-
|| ENTREPRISE AGRICOLE
|| ______
|| ______
|| ______
|| ______
|-
|| tailler FORMATION, PLANT AGE
|| jours
|| ______
|| 15-20
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| ______
|| 2-3
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 40,0
|| ______
|| ______
|-
|| Temps INTERPASES
|| jours
|| ______
|| 3-4
|| ______
|-
|| TEMPS DURÉE récolter
|| mois
|| ______
|| 1-1,5 meses
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 5,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| ______
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| ______
|| 1-2
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 94,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 6,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 18,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 300,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,9
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 65,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 2,6
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 43,3
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,2
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 20,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 3,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 0,9
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 15,0
|| ______
|| ______
|-
|}
{{AutoCat}}
s3bv5ynvloclsrnnfabqlbp3loy4kx9
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Poivrons
2
74707
764382
638489
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Poivrons]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Poivrons]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638489
wikitext
text/x-wiki
{|
|| '''Poivrons'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - OPTIMA
|| Cº
|| 22,0
|| 20-25
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 10,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 15,0
|| ______
|| ______
|-
|| Tª diurne optimale
|| Cº
|| ______
|| 20-25
|| ______
|-
|| Tª nuit optimale
|| Cº
|| ______
|| 16-18
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 32,0
|| ______
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| 13,0
|| ______
|| ______
|-
|| fleur-en journée
|| Cº
|| ______
|| 26-28
|| ______
|-
|| Fleur-nuit
|| Cº
|| ______
|| 16-18
|| ______
|-
|| fructification en journée
|| Cº
|| ______
|| 26-28
|| ______
|-
|| fructification nuit
|| Cº
|| ______
|| 16-18
|| ______
|-
|| HAUTEUR M. (FROID EN TROPIQUES) optimale
|| m
|| ______
|| 400-800
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 2,5-1,25
|| MODÉRÉMENT
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| 5,5
|| ______
|| MODÉRÉMENT
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,5
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 185,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,3
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 6,2
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 140,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 160,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 130,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,7
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 5,3
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 2,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,3
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 6,7
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 3-5
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 6,2
|| 6,5-5
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 225,0
|| 150-300
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| ______
|| 3-4
|| ______
|-
|| PÉPINIÈRE m2 / HA CULTIVÉ
|| m2/ha
|| 10,0
|| ______
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 300,0
|| ______
|| ______
|-
|| PROFONDEUR CM.
|| cm
|| 0,5
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 30-45
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 30.000,0
|| ______
|| ______
|-
|| PLANTATION distance lignes
|| m
|| 0,8
|| 0,75-0,90
|| ______
|-
|| plantation distance plantes
|| m
|| 0,5
|| 0,40-0,60
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| ______
|| 2,5-3
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| Temps INTERPASES
|| jours
|| ______
|| 2-3
|| ______
|-
|| TEMPS DURÉE récolter
|| mois
|| ______
|| 2-3
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 7-10
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| ______
|| 1-3
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 94,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 6,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 20,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 333,3
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 4,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 76,7
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 2,4
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 40,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,8
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 30,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 3,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 0,9
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 15,0
|| ______
|| ______
|-
|}
{{AutoCat}}
kwabz2e75ul5ih0kq6npvy2eyz4fn10
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Aubergines
2
74708
764361
638474
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Aubergines]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Aubergines]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638474
wikitext
text/x-wiki
{|
|| '''Aubergines'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - MINIMUM
|| Cº
|| 15,0
|| ______
|| ______
|-
|| GERMINATION - maxim
|| Cº
|| 35,0
|| ______
|| ______
|-
|| GERMINATION - OPTIMA
|| Cº
|| 22,0
|| 20-25
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 15,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 20-29
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 35,0
|| ______
|| ______
|-
|| GERMINATION-Semis
|| Cº
|| ______
|| 20-32
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| 15,0
|| ______
|| ______
|-
|| fleur
|| Cº
|| ______
|| 20-30
|| ______
|-
|| fructification
|| Cº
|| ______
|| 20-30
|| ______
|-
|| fructification minimum
|| Cº
|| 15,0
|| ______
|| ______
|-
|| LUMIÈRE
|| ______
|| ______
|| ______
|| ______
|-
|| JOUR LONG
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| HUMIDITE AIR % RH
|| %
|| ______
|| 50-65
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| LOURDS - ARGILE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| ______
|| 5,5-6,8
|| MODÉRÉMENT
|-
|| pH maximale
|| pH
|| 8,0
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 216,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 21,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 192,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,2
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,7
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 6,4
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 270,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 105,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 270,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 9,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,5
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 9,0
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 3-5
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 3,7
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 250,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| 4-6
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 1,2
|| 1-1,3
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,6
|| 0,5-0,7
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| jours
|| ______
|| 100-125
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| Temps INTERPASES
|| jours
|| ______
|| 3-4
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 4-6
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| ______
|| 1-2
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 93,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 7,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 25,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 357,1
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 5,9
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 84,3
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 3,5
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 50,4
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 3,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 42,9
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,9
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,0
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 14,3
|| ______
|| ______
|-
|}
{{AutoCat}}
rbml5hs6pown5w3fpadzazrvy2jbui3
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Concombres
2
74709
764369
638481
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Concombres]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Concombres]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638481
wikitext
text/x-wiki
{|
|| '''Concombres'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| 25,0
|| ______
|| ______
|-
|| GERMINATION-Semis
|| Cº
|| 27,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| 21,0
|| ______
|| ______
|-
|| fructification
|| Cº
|| 19,0
|| ______
|| ______
|-
|| LUMIÈRE
|| ______
|| ______
|| ______
|| ______
|-
|| JOUR COURT
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 5,5-7
|| ______
|-
|| PH MINIMUM
|| pH
|| 5,5
|| ______
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 2,5
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 50,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 35,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,7
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,2
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 2,5
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 50,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 140,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,7
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 1,7
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 2,5
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 2,7
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,7
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 6,7
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 2-3
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 28,6
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 3-5
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 4.750,0
|| 4.500-5.000
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| 2,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| ______
|| ______
|-
|| TEMPS DURÉE récolter
|| mois
|| 1,0
|| ______
|| ______
|-
|| Fleur-récolte
|| jours
|| ______
|| 55-60
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| CALIBRE-produit - long
|| cm
|| 27,0
|| 20-30
|| ______
|-
|| CALIBRE-produit - Largeur
|| cm
|| ______
|| 3-6 cm
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 10-12
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| ______
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| jours
|| 14,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 95,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 5,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 16,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 320,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 72,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 34,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 0,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 10,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,0
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 0,7
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 14,0
|| ______
|| ______
|-
|}
{{AutoCat}}
cge2j356kz5oy3x5nelvqcxhd0ijrbr
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Courgettes
2
74710
764370
638482
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Courgettes]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Courgettes]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638482
wikitext
text/x-wiki
{|
|| '''Courgettes'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - MINIMUM
|| Cº
|| 10,0
|| ______
|| ______
|-
|| GERMINATION - OPTIMA
|| Cº
|| 22,0
|| 20-25
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 8,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 35,0
|| ______
|| ______
|-
|| GERMINATION-Semis
|| Cº
|| ______
|| 21-35
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 18-24
|| ______
|-
|| fleur
|| Cº
|| ______
|| 20-25
|| ______
|-
|| Fleur-maximale
|| Cº
|| 35,0
|| ______
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| HUMIDITE AIR % RH
|| %
|| ______
|| 65-80
|| ______
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 110,0
|| 100-120
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 75,0
|| 70-80
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 125,0
|| 120-130
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 2,1
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,6
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 165,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 165,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 35,0
|| 30-40
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,4
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/4
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 3/4
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 4-5
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| ______
|| 7-8
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| ______
|| 4-5
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 1,1
|| 1-1,2
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,9
|| 0,8-1
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 10,0
|| ______
|| ______
|-
|| RETIRER, JOURS DEPUIS REPOUSSE
|| jours
|| 9,0
|| 8-10
|| ______
|-
|| RETIRER, N ° - FEUILLES DES PLANTES
|| nº
|| ______
|| 2-3
|| ______
|-
|| TRAVAIL
|| ______
|| ______
|| ______
|| ______
|-
|| 1°- terre vers le haut, TEMPS APRÈS naissance
|| jours
|| ______
|| 15-20
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| Poids moyen
|| gr
|| 225,0
|| 200-250
|| ______
|-
|| Fleur-récolte
|| jours
|| 55,0
|| 45-65
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| CALIBRE-produit - long
|| cm
|| ______
|| 15-18
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 5-10
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| ______
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| jours
|| 10,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 95,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 5,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 17,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 340,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,1
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 62,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 2,5
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 50,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 20,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 6,0
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,2
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 24,0
|| ______
|| ______
|-
|}
{{AutoCat}}
2ffq3ofig8tqh0rm0jsg1o9imis7xo2
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Melons
2
74711
764377
638486
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Melons]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Melons]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638486
wikitext
text/x-wiki
{|
|| '''Melons'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - MINIMUM
|| Cº
|| 15,0
|| ______
|| ______
|-
|| ice plant
|| Cº
|| 1,0
|| ______
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 12,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 24-34
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| ______
|| 35-40
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| ______
|| 22-28
|| ______
|-
|| TEMPERATURE - maxime Germination
|| Cº
|| 39,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 18-24
|| ______
|-
|| fleur
|| Cº
|| ______
|| 20-23
|| ______
|-
|| Fleur-minimum
|| Cº
|| 18,0
|| ______
|| ______
|-
|| MATURATION
|| Cº
|| ______
|| 25-30
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| HUMIDITE AIR% HR-développement
|| %
|| ______
|| 65-75
|| ______
|-
|| HUMIDITE AIR% HR-fleur
|| %
|| ______
|| 60-70
|| ______
|-
|| AIR HUMIDITE% HR-fructification
|| %
|| ______
|| 55-65
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| dS/m affecte les cultures
|| dS/m
|| 2,2
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| PREFER
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| AZOTE-feuille-assez
|| ppm
|| 10.000,0
|| ______
|| ______
|-
|| azote Feuille-PAUVRE
|| ppm
|| 5.000,0
|| ______
|| ______
|-
|| PHOSPHORE-feuille-assez
|| ppm
|| 3.000,0
|| ______
|| ______
|-
|| PHOSPHORE Feuille-PAUVRE
|| ppm
|| 1.500,0
|| ______
|| ______
|-
|| POTASSIUM-feuille-assez
|| %
|| 3,0
|| ______
|| ______
|-
|| POTASSIUM Feuille-PAUVRE
|| %
|| 3,0
|| ______
|| ______
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 225,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 30,0
|| 20-40
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 2,5
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,7
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,5
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,7
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 10,0
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 1-2
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 36,0
|| 25-47
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 35,0
|| 20-50
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 4-5
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 2,0
|| ______
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 1,0
|| ______
|| ______
|-
|| No. - GRAINES / trou
|| nº
|| ______
|| 4-5
|| ______
|-
|| TABLE, LARGEUR ENTRE CENTRES
|| m
|| 3,0
|| 2,5-3,5
|| ______
|-
|| TABLE, DISTANCE ENTRE LES PLANTES
|| m
|| 0,9
|| 0,6-1,25
|| ______
|-
|| Tableau n ° - LIGNES
|| nº
|| 2,0
|| ______
|| ______
|-
|| TROU PROFONDEUR
|| cm
|| 20,0
|| ______
|| ______
|-
|| TROU Largeur
|| cm
|| 40,0
|| ______
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 2,0
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 4.250,0
|| 4.000-4.500
|| ______
|-
|| GRAINES PROFONDEUR
|| cm
|| 2,5
|| ______
|| ______
|-
|| RETIRER No. PLANTES TROU
|| nº
|| 2,0
|| ______
|| ______
|-
|| RETIRER, JOURS DEPUIS REPOUSSE
|| jours
|| 10,0
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| ______
|| 3-4
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 92,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 8,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 28,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 350,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 6,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 82,5
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 5,7
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 71,3
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 0,9
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 11,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,1
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 13,8
|| ______
|| ______
|-
|}
{{AutoCat}}
7telz7lirsu6hdclsegp8pybn8ynxkc
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Potirons
2
74712
764384
638490
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Potirons]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Potirons]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638490
wikitext
text/x-wiki
{|
|| '''Potirons'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 2,5-1,25
|| MODÉRÉMENT
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| PH MINIMUM
|| pH
|| 6,0
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| PREFER
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| FERTILITÉ
|| ______
|| ______
|| ______
|| PREFER
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 125,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,5
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 6,3
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 27,0
|| 20-30
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,4
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 286,0
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| ______
|| 3-4
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 3-4
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 3,0
|| ______
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 3,0
|| ______
|| ______
|-
|| No. - GRAINES / trou
|| nº
|| ______
|| 3-4
|| ______
|-
|| TROU PROFONDEUR
|| cm
|| 20,0
|| ______
|| ______
|-
|| TROU Largeur
|| cm
|| 40,0
|| ______
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 1,5
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 1.100,0
|| 900-1.300
|| ______
|-
|| GRAINES PROFONDEUR
|| cm
|| 2,5
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| ______
|| 5-6
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 20,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 8-12
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 92,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 8,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 26,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 325,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 6,5
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 81,3
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 2,7
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 33,8
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 0,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 6,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,0
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 12,5
|| ______
|| ______
|-
|}
{{AutoCat}}
48nxl944jb4fawig87y0rxxj1j6wzyh
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Pastèques
2
74713
764380
638488
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Pastèques]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Pastèques]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638488
wikitext
text/x-wiki
{|
|| '''Pastèques'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - MINIMUM
|| Cº
|| 15,0
|| ______
|| ______
|-
|| GERMINATION - OPTIMA
|| Cº
|| 25,0
|| ______
|| ______
|-
|| ice plant
|| Cº
|| 0,0
|| ______
|| NE TOLÈRE PAS
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 12,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 24-34
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| ______
|| 35-40
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 18-24
|| ______
|-
|| fleur
|| Cº
|| ______
|| 18-20
|| ______
|-
|| Fleur-minimum
|| Cº
|| 18,0
|| ______
|| ______
|-
|| MATURATION
|| Cº
|| ______
|| 25-30
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| ______
|| 5-6,8
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| PREFER
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 40,0
|| 25-55
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 150,0
|| 60-240
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,4
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,9
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 110,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 225,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,4
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,4
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 9,0
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 12,0
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 1-2
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 115,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| 30,0
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 3,0
|| ______
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 2,0
|| ______
|| ______
|-
|| No. - GRAINES / trou
|| nº
|| ______
|| 4-5
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 1,0
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 1.600,0
|| 1.400-1.800
|| ______
|-
|| GRAINES PROFONDEUR
|| cm
|| 2,5
|| ______
|| ______
|-
|| RETIRER No. PLANTES TROU
|| nº
|| 2,0
|| ______
|| ______
|-
|| RETIRER, JOURS DEPUIS REPOUSSE
|| jours
|| 10,0
|| ______
|| ______
|-
|| TRAVAIL
|| ______
|| ______
|| ______
|| ______
|-
|| défoncer
|| cm
|| ______
|| 25-30
|| ______
|-
|| TROU, PROFONDEUR
|| cm
|| 20,0
|| ______
|| ______
|-
|| TROU, LARGEUR
|| cm
|| 40,0
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| jours
|| 90,0
|| 75-100
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| ______
|| ______
|-
|| No. - FRUITS / Ha
|| nº/ha
|| 5.000,0
|| 3.500-6.500
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 8-10
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| 3,0
|| 2-4
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 92,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 8,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 30,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 375,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 7,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 95,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 6,2
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 77,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 0,4
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 5,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,9
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 0,6
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 7,6
|| ______
|| ______
|-
|}
{{AutoCat}}
7lr5vz95g367urdlkimg3kqr3700zw7
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Chayote
2
74714
764364
638476
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Chayote]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Chayote]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638476
wikitext
text/x-wiki
{|
|| '''Chayote'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 20,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| 25,0
|| ______
|| ______
|-
|| HAUTEUR M. (FROID EN TROPIQUES) optimale
|| m
|| ______
|| 300-1.200
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| MM. CYCLE PLANT
|| mm
|| 1.200,0
|| 900-1.400
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| PREFER
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 130,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 20,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 4,3
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 2,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,7
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/4
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 3/4
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| No. - plantes / trou
|| nº
|| 4,0
|| ______
|| ______
|-
|| largeur de lignes.
|| cm
|| 4,5
|| ______
|| ______
|-
|| LARGEUR ENTRE PLANTES M.
|| m
|| 4,5
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 390,0
|| 350-420
|| ______
|-
|| TRANSPLANTATION, JOURS DE SEMIS/PLANTATION
|| jours
|| 15,0
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| 3,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| Poids moyen
|| gr
|| 500,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 10,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 85-90
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| mois
|| 1,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 94,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 6,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 11,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 183,3
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 4,5
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 75,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 28,3
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 28,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,7
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 0,8
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 13,3
|| ______
|| ______
|-
|}
{{AutoCat}}
2rhv3kqx3vzmja8y074ictg76vpe8se
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Brocolis
2
74715
764362
638475
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Brocolis]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Brocolis]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638475
wikitext
text/x-wiki
{|
|| '''Brocolis'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| -8 /-10
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| ______
|| 4-5
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 25,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 15-18
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| RÉSISTANCE À LA SÉCHERESSE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6-6,8
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 2,8
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 225,0
|| 150-300
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 75,0
|| 50-100
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 225,0
|| 150-300
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 22,0
|| 15-30
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 11,3
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,8
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 11,3
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 1-3
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 0,6
|| 0,5-0,8
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,4
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 11,0
|| 10-30
|| ______
|-
|| Temps INTERPASES
|| jours
|| ______
|| 2-3
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 89,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 11,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 34,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 309,1
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 6,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 60,4
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 15,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,6
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 23,6
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,4
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 3,6
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 2,8
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 25,5
|| ______
|| ______
|-
|}
{{AutoCat}}
cfihzbxgnsdogva8b9rvz05coiqm981
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux fleurs
2
74716
764367
638479
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Choux fleurs]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux fleurs]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638479
wikitext
text/x-wiki
{|
|| '''Choux fleurs'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| 0,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 15-21
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 26,0
|| ______
|| ______
|-
|| INDUCTION FLORAL-cycle court
|| Cº
|| 15,0
|| ______
|| ______
|-
|| INDUCTION FLORAL-cycle vers la fin
|| Cº
|| ______
|| 6-10
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| POROSITÉ-aéré
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6,5-7
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| FERTILITÉ
|| ______
|| ______
|| ______
|| PREFER
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| BORE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 165,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 165,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 130,0
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 22,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 4,1
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 250,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,8
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 9,1
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 3,6
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 5,5
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 9,1
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 11,4
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 13,6
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 1-3
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 3,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 8-10
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 8-10
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 0,6
|| 0,5-0,8
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,4
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 37.000,0
|| 30.000-35.000
|| ______
|-
|| TRANSPLANTATION, JOURS DE SEMIS/PLANTATION
|| jours
|| ______
|| 25-30
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| 2,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 22,0
|| 15-30
|| ______
|-
|| No. - FRUITS / Ha
|| nº/ha
|| 27.000,0
|| 25.000-30.000
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 1,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 91,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 9,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 27,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 300,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 6,2
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 68,9
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 2,6
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 28,9
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 3,6
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 40,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,1
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,7
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 18,9
|| ______
|| ______
|-
|}
{{AutoCat}}
fyovg9yt4lhz0qyxoxrengxwjut4ec5
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux pommés
2
74717
764368
638480
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Choux pommés]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux pommés]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638480
wikitext
text/x-wiki
{|
|| '''Choux pommés'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| -8 /-10
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| ______
|| 4-5
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 25,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 15-18
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| RÉSISTANCE À LA SÉCHERESSE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 3,75-2,5
|| TOLÉRANTE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6-6,8
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,8
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| AZOTE-feuille-assez
|| ppm
|| 8.000,0
|| ______
|| ______
|-
|| azote Feuille-PAUVRE
|| ppm
|| 5.000,0
|| ______
|| ______
|-
|| PHOSPHORE-feuille-assez
|| ppm
|| 3.000,0
|| ______
|| ______
|-
|| PHOSPHORE Feuille-PAUVRE
|| ppm
|| 2.500,0
|| ______
|| ______
|-
|| POTASSIUM-feuille-assez
|| %
|| 2,0
|| ______
|| ______
|-
|| POTASSIUM Feuille-PAUVRE
|| %
|| 2,0
|| ______
|| ______
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| BORE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 200,0
|| 180-215
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 65,0
|| 60-72
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 200,0
|| 180-215
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 200,0
|| 180-215
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 35,0
|| 30-40
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,1
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 2,4
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 7,1
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,1
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,3
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 250,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 160,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 250,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 30,0
|| 25-35
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,7
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 8,3
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 2,7
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 5,3
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 6,7
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 8,3
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT PLANT-n º aportación
|| nº
|| ______
|| 1-3
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 3,2
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 8-10
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 300,0
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 8-10
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 0,6
|| 0,5-0,8
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,4
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 37.000,0
|| 30.000-35.000
|| ______
|-
|| TRANSPLANTATION, JOURS DE SEMIS/PLANTATION
|| jours
|| ______
|| 25-30
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| 2,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| 25-35
|| ______
|-
|| No. - FRUITS / Ha
|| nº/ha
|| 27.000,0
|| 25.000-30.000
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 1,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 92,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 8,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 25,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 312,5
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 5,8
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 72,5
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 3,2
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 40,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 31,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,3
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 16,3
|| ______
|| ______
|-
|}
{{AutoCat}}
9bwjiaz997tmixvwqlzfndm2qt1ym4b
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux de Chine
2
74718
764366
638478
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Choux de Chine]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Choux de Chine]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638478
wikitext
text/x-wiki
{|
|| '''Choux de Chine'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 7,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 24,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 18-20
|| ______
|-
|| création cœur
|| Cº
|| ______
|| 15-16
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| francs légers
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6,5-7
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,8
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 115,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 18,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,3
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,8
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,3
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,3
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 0,5
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| ______
|| 8-10
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 300,0
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 8-10
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 0,6
|| 0,5-0,8
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,4
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 37.000,0
|| 30.000-35.000
|| ______
|-
|| TRANSPLANTATION, JOURS DE SEMIS/PLANTATION
|| jours
|| ______
|| 25-30
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| mois
|| 2,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 35,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 1,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 96,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 4,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 16,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 400,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,2
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 80,0
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 0,0
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,2
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 30,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 5,0
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,2
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 30,0
|| ______
|| ______
|-
|}
{{AutoCat}}
7kiiup60scucdg0s6l5m4pmc4gv8htp
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Laitue
2
74719
764375
647571
2026-04-22T08:54:27Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Laitue]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Laitue]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
647571
wikitext
text/x-wiki
{|
|| '''Laitue'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| ºC
|| ______
|| ______
|| SENSIBLE
|-
|| Air - minimum growth zéro température vegetation
|| ºC
|| ______
|| 4-5
|| ______
|-
|| GERMINATION-Semis
|| ºC
|| ______
|| 15-20
|| ______
|-
|| TEMPÉRATURE - optimale Germination
|| ºC
|| 30,0
|| ______
|| ______
|-
|| développement végétatif
|| ºC
|| ______
|| 15-20
|| ______
|-
|| développement végétatif-nuit
|| ºC
|| 20,0
|| minima
|| ______
|-
|| HAUTEUR M. (FROID EN TROPIQUES) optimale
|| m
|| ______
|| 500-800
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| RÉSISTANCE À LA SÉCHERESSE
|| ______
|| ______
|| ______
|| NE TOLÈRE PAS
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 3,75-2,5
|| TOLÉRANTE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| ______
|| 6-6,8
|| SENSIBLE
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,3
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MATIÈRE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| TRÈS EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| AZOTE-feuille-assez
|| ppm
|| 8.000,0
|| ______
|| ______
|-
|| azote Feuille-PAUVRE
|| ppm
|| 4.000,0
|| ______
|| ______
|-
|| PHOSPHORE-feuille-assez
|| ppm
|| 3.000,0
|| ______
|| ______
|-
|| PHOSPHORE Feuille-PAUVRE
|| ppm
|| 2.000,0
|| ______
|| ______
|-
|| POTASSIUM-feuille-assez
|| %
|| 3,0
|| ______
|| ______
|-
|| POTASSIUM Feuille-PAUVRE
|| %
|| 2,0
|| ______
|| ______
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| BORE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 65,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 25,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 12,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,6
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 4,8
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,6
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 0,5
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 130,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 160,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 45,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 22,0
|| 20-25
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 4,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 5,2
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 6,4
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 1,2
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,8
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 2,4
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 2,4
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 3,6
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 4,8
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 0,7
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 800,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 3,0
|| ______
|| ______
|-
|| GERMINATION, OPTIMUMS TEMPÉRATURE
|| jours
|| 8,0
|| ______
|| ______
|-
|| GRAINES PÉPINIÈRE, GRS / HA. CULTIVÉ
|| gr/ha
|| 300,0
|| ______
|| ______
|-
|| PROFONDEUR CM.
|| cm
|| 0,6
|| ______
|| ______
|-
|| TRANSPLANTATION, PLANT HAUTEUR cm.
|| cm
|| 8,0
|| ______
|| ______
|-
|| TRANSPLANTATION, LONGUEUR FEUILLES No.
|| nº
|| ______
|| 5-6
|| ______
|-
|| TABLE, LARGEUR ENTRE CENTRES
|| m
|| 0,9
|| 0,8-1,0
|| ______
|-
|| Tableau n ° - LIGNES
|| nº
|| 2,0
|| ______
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 2,5
|| 2-3
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 35.000,0
|| ______
|| ______
|-
|| TRANSPLANTATION, JOURS DE SEMIS/PLANTATION
|| jours
|| ______
|| 30-40
|| ______
|-
|| PLANTATION distance lignes
|| m
|| 0,5
|| ______
|| ______
|-
|| plantation distance plantes
|| m
|| 0,3
|| 0,25-0,30
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 1,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| 3,0
|| 2-4
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 96,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 4,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 13,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 325,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 2,2
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 55,8
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 0,9
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 23,5
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,1
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 27,5
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 5,5
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,4
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 33,8
|| ______
|| ______
|-
|}
{{AutoCat}}
35jh9aa6ld63qmlkycmpqsdlzv4d9um
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Chicorée
2
74720
764365
638477
2026-04-22T08:54:25Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Chicorée]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Chicorée]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638477
wikitext
text/x-wiki
{|
|| '''Chicorée'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 7,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 30,0
|| ______
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| ______
|| 22-24
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 16-18
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| RÉSISTANCE À LA SÉCHERESSE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| francs légers
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| CAPACITÉ AU CHAMP %
|| %
|| 60,0
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| pH
|| ______
|| 5-6,8
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 54,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 24,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 135,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 24,6
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / Ha
|| ue/ha
|| 9,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 1,8
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 0,8
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 0,8
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 0,3
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 135,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 55,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 180,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,8
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 600,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 3,0
|| ______
|| ______
|-
|| DENSITÉ, GR. GRAINES-m2
|| gr/ha
|| ______
|| 1-3
|| ______
|-
|| DENSITÉ, PLANTE/REPOUSSE/TUBERCULES-m2
|| plantes/m2
|| 450,0
|| 300-600
|| ______
|-
|| TRANSPLANTATION, JOURS APRÈS SEMIS
|| jours
|| ______
|| 30-35
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 2,5
|| 2-3
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 50.000,0
|| 45.000-55.000
|| ______
|-
|| PLANTATION distance lignes
|| m
|| 0,5
|| 0,4-0,5
|| ______
|-
|| plantation distance plantes
|| m
|| 0,3
|| 0,25-0,40
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 30,0
|| ______
|| ______
|-
|| cycle récolte
|| jours
|| 100,0
|| 80-120
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 4,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| 4,0
|| 2-6
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 94,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 6,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 17,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 283,3
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,4
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 55,8
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 0,3
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 4,2
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 3,1
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 51,7
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,2
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 3,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,3
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 20,8
|| ______
|| ______
|-
|}
{{AutoCat}}
3xxc5sm5f9ekzq618wipr9smz6yhrgn
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Épinards
2
74721
764387
638492
2026-04-22T08:54:28Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Épinards]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Épinards]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638492
wikitext
text/x-wiki
{|
|| '''Épinards'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - maxim
|| Cº
|| 26,0
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| TOLÉRANTE
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 5,0
|| ______
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| 15,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 15-18
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| RÉSISTANCE À LA SÉCHERESSE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| POROSITÉ-aéré
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| PREFER
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6-6,8
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 2,0
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| FERTILITÉ
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| BORE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 95,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 35,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 4,8
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,8
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 5,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 115,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,5
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 9,5
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 115,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| ______
|| ______
|-
|| GERMINATION, TEMPÉRATURE FROIDE
|| semaines
|| 3,0
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| cm
|| 35,0
|| 25-40
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 40,0
|| 30-50
|| ______
|-
|| GRAINES PROFONDEUR
|| cm
|| ______
|| 1-2
|| ______
|-
|| RETIRER, distance entre plantes
|| cm
|| 14,0
|| 12-15
|| ______
|-
|| RETIRER, No. - PLANTES -m2
|| plantes/m2
|| 40,0
|| 30-50
|| ______
|-
|| RETIRER, N ° - FEUILLES DES PLANTES
|| nº
|| ______
|| 4-5
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| ______
|| ______
|-
|| Nª RECUEILLIS PAR CYCLE
|| nº
|| ______
|| 5-6
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 1-0
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| 3,0
|| 2-4
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 91,4
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 8,6
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 23,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 267,4
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,6
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 41,9
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 0,4
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 4,7
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,2
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 25,6
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,4
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 4,7
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 2,9
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 33,7
|| ______
|| ______
|-
|}
{{AutoCat}}
n9t07qocctdir32c5u5pmyf7vsuiquh
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Feuilles de bettes
2
74722
764372
638484
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Feuilles de bettes]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Feuilles de bettes]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638484
wikitext
text/x-wiki
{|
|| '''Feuilles de bettes'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| TOLÉRANTE
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 5,0
|| ______
|| ______
|-
|| TEMPERATURE AIR - optimale culture
|| Cº
|| ______
|| 15-25
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| ______
|| 27-33
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| 5,0
|| ______
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| 30,0
|| 30-35
|| ______
|-
|| HAUTEUR M. (FROID EN TROPIQUES)
|| m
|| ______
|| ______
|| PREFER
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| HUMIDITE AIR % RH
|| %
|| ______
|| 60-90
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| PREFER
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6-6,8
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 40,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 80,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 3,2
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,6
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,2
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 35,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 1,4
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 15,2
|| ______
|| ______
|-
|| No. - GRAINES / GR.
|| graines/gr
|| 60,0
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 4,0
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 0,5
|| 0,4-0,6
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,3
|| ______
|| ______
|-
|| No. - GRAINES / trou
|| nº
|| ______
|| 3-4
|| ______
|-
|| KG. GRAINES-TUBERCULES-bulbes/HA.
|| kg/ha
|| 9,0
|| 8-10
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 86.000,0
|| ______
|| ______
|-
|| TRANSPLANTATION, nº de feuilles
|| nº
|| ______
|| 5-6
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| début récolter ÂGE PLANTE
|| jours
|| ______
|| 60-75
|| ______
|-
|| début récolter -LONGUEUR
|| cm
|| 25,0
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 25,0
|| ______
|| ______
|-
|| Temps INTERPASES
|| jours
|| 14,0
|| 12-15
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 0,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| jours
|| ______
|| 10-12
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 92,6
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 7,4
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 20,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 270,3
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 4,1
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 55,8
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,1
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 14,9
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,1
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 28,4
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,1
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,9
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 25,7
|| ______
|| ______
|-
|}
{{AutoCat}}
qcmu6am1zge6l844q25hdijynee1cn9
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Céleri
2
74723
764371
638483
2026-04-22T08:54:26Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Céleri]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Céleri]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638483
wikitext
text/x-wiki
{|
|| '''Céleri'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| GERMINATION - maxim
|| Cº
|| 25,0
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| SENSIBLE
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| ______
|| 7-8
|| ______
|-
|| TEMPERATURE AIR - MINIMUM culture
|| Cº
|| ______
|| 8-10
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 25,0
|| ______
|| ______
|-
|| GERMINATION-Semis
|| Cº
|| ______
|| 15-22
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| ______
|| 13-15
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| ______
|| 17-20
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 15-22
|| ______
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| DEMIE - FRANK
|| ______
|| ______
|| ______
|| PREFER
|-
|| sols profonds
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| CAPACITÉ DE RÉTENTION
|| ______
|| ______
|| ______
|| RÉGULIER
|-
|| HUMIDES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| CONSOMMATION-M 3 HECTARE - cycle court
|| m3/ha
|| 4.000,0
|| 3.500-4.500
|| ______
|-
|| CONSOMMATION-M 3 HECTARE - cycle long
|| m3/ha
|| 7.000,0
|| ______
|| ______
|-
|| SECHERESSE-TOLERANCE
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| pH maximale
|| pH
|| 8,0
|| ______
|| ______
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 6,8-7,2
|| ______
|-
|| dS/m affecte les cultures
|| dS/m
|| 1,9
|| 1,8-2
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| MATIERE ORGANIQUE - HUMUS
|| ______
|| ______
|| ______
|| PREFER
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| AZOTE-feuille-assez
|| ppm
|| 10.000,0
|| ______
|| ______
|-
|| azote Feuille-PAUVRE
|| ppm
|| 5.000,0
|| ______
|| ______
|-
|| PHOSPHORE-feuille-assez
|| ppm
|| 3.500,0
|| ______
|| ______
|-
|| PHOSPHORE Feuille-PAUVRE
|| ppm
|| 2.000,0
|| ______
|| ______
|-
|| POTASSIUM-feuille-assez
|| %
|| 6,0
|| ______
|| ______
|-
|| POTASSIUM Feuille-PAUVRE
|| %
|| 4,0
|| ______
|| ______
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| MOLYBDÈNE-DÉFICIENCES
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| BORE-DÉFICIENCES
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,4
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 1,8
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 7,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 2,6
|| ______
|| ______
|-
|| Mg-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 0,2
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 190,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 140,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 560,0
|| ______
|| ______
|-
|| Fumier / Ha
|| tonne/ha
|| 30,0
|| 25-30
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 3,8
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 2,8
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 11,2
|| ______
|| ______
|-
|| AZOTE-PRÉSEMIS
|| %
|| ______
|| 1/3
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 2/3
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| graine-POIDS (Gr / 1000 graine)
|| gr
|| 0,4
|| ______
|| ______
|-
|| GRAINES ans capacité germinative
|| années
|| 5,0
|| ______
|| ______
|-
|| DENSITÉ, GR. GRAINES-m2
|| gr/ha
|| 0,5
|| ______
|| ______
|-
|| DENSITÉ, PLANTE/REPOUSSE/TUBERCULES-m2
|| plantes/m2
|| 300,0
|| 250-350
|| ______
|-
|| TRANSPLANTATION, PLANT HAUTEUR cm.
|| cm
|| 15,0
|| ______
|| ______
|-
|| TRANSPLANTATION, LONGUEUR FEUILLES No.
|| nº
|| ______
|| 4-5
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,2
|| 0,20
|| ______
|-
|| TRANSPLANTATION, nº de feuilles
|| nº
|| ______
|| 3-4
|| ______
|-
|| TRAVAIL
|| ______
|| ______
|| ______
|| ______
|-
|| "CULTURE-DÉSHERBAGE
"
|| ______
|| ______
|| ______
|| EXIGEANT
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 50,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 2,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| semaines
|| 6,0
|| 5-7
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 88,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 12,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 42,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 350,0
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 9,2
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 76,7
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,6
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 13,3
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 1,8
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 15,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,5
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 1,5
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 12,5
|| ______
|| ______
|-
|}
{{AutoCat}}
rejcj6o9cr2ux1qbe9meiowzpnvt7uq
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Asperges
2
74724
764360
730450
2026-04-22T08:54:24Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Asperges]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Asperges]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638473
wikitext
text/x-wiki
{|
|| '''Asperges'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| frozen tuber
|| Cº
|| ______
|| ______
|| TRÈS TOLÉRANT
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| ______
|| 4-5
|| ______
|-
|| TEMPERATURE AIR - maximale
|| Cº
|| 40,0
|| ______
|| ______
|-
|| TEMPERATURE - minimale germinative
|| Cº
|| 10,0
|| ______
|| ______
|-
|| TEMPERATURE - optimale Germination
|| Cº
|| ______
|| 15-30
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 12-25
|| ______
|-
|| développement végétatif-en journée
|| Cº
|| 15,0
|| minima
|| ______
|-
|| développement végétatif-nuit
|| Cº
|| 10,0
|| minima
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 3,75-2,5
|| TOLÉRANTE
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| légers - SANDY
|| ______
|| ______
|| ______
|| PREFER
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| USINE de tolérance au pH acide
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| GAMME OPTIMUM pH
|| pH
|| ______
|| 7,5-8
|| ______
|-
|| PH MINIMUM
|| pH
|| 6,5
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| ZINC-DÉFICIENCES
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| MANGANÈSE-DÉFICIENCES
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| CUIVRE-DÉFICIENCES
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 95,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 25,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / Ha
|| ue/ha
|| 15,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 24,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 6,5
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 30,0
|| ______
|| ______
|-
|| Ca-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 3,5
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 160,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 50,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 75,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 100,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 30,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 40,0
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 50,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 12,5
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 18,8
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 25,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 25,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 37,5
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 50,0
|| ______
|| ______
|-
|| AZOTE-SEMIS
|| %
|| ______
|| 1/2
|| ______
|-
|| AZOTE-DÉVELOPPEMENT-PLANT
|| %
|| ______
|| 1/2
|| ______
|-
|| PHOSPHORE-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| POTASSIUM-PRÉSEMIS
|| %
|| 100,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| rhizome poids
|| gr
|| 60,0
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 1,4
|| 1,25 -1,50
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,3
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 25.000,0
|| ______
|| ______
|-
|| Rhizome profondeur
|| cm
|| 12,0
|| 10-15
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 4,0
|| ______
|| ______
|-
|| temps durée Plantation
|| années
|| 10,0
|| 8-12
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| ______
|| 2-3
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| 95,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 93,2
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 6,8
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 20,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 294,1
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 3,9
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 57,1
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,9
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 27,6
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 2,1
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 30,9
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,1
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 1,8
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 2,2
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 32,4
|| ______
|| ______
|-
|}
{{AutoCat}}
m5nodjo4e0gxkfrl1h8btczxv1axbs4
Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Artichauts
2
74725
764359
638472
2026-04-22T08:54:24Z
JackPotte
5426
JackPotte a déplacé la page [[Agrodatabase/21 - Prontuaire culture - Données/Artichauts]] vers [[Utilisateur:Agrodata/Agrodatabase/21 - Prontuaire culture - Données/Artichauts]] sans laisser de redirection : Intéressant mais inédit et supprimé ailleurs pour cause de spam transwiki "not personal host" (et special:nuke ne permet plus la suppression de masse)
638472
wikitext
text/x-wiki
{|
|| '''Artichauts'''
|| Unités
|| Moyenne
|| Rang
|| Évaluation
|-
|| '''CLIMAT'''
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE
|| ______
|| ______
|| ______
|| ______
|-
|| ice plant
|| Cº
|| ______
|| ______
|| TOLÉRANTE
|-
|| Air - minimum growth zero temperature vegetation
|| Cº
|| 5,0
|| ______
|| ______
|-
|| développement végétatif
|| Cº
|| ______
|| 15-18
|| ______
|-
|| EAU
|| ______
|| ______
|| ______
|| ______
|-
|| BORe-EAU IRRIGATION
|| mg/lt
|| ______
|| 2,5-1,25
|| MODÉRÉMENT
|-
|| '''SOL'''
|| ______
|| ______
|| ______
|| ______
|-
|| PROPRIÉTÉS PHYSIQUE DES SOLS
|| ______
|| ______
|| ______
|| ______
|-
|| légers - SANDY
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| sols profonds
|| ______
|| ______
|| ______
|| PREFER
|-
|| EAU DU SOL
|| ______
|| ______
|| ______
|| ______
|-
|| DRAINED
|| ______
|| ______
|| ______
|| PREFER
|-
|| GORGÉS D’EAU
|| ______
|| ______
|| ______
|| SENSIBLE
|-
|| PROPRIÉTÉS PHYSIQUES ET CHIMIQUES
|| ______
|| ______
|| ______
|| ______
|-
|| TOLÉRANCE PLANTES salinité du sol
|| ______
|| ______
|| ______
|| MODÉRÉMENT
|-
|| TOLÉRANCE PLANTES alcalinité du sol
|| ______
|| ______
|| ______
|| TOLÉRANTE
|-
|| ÉLÉMENTS NUTRITIFS
|| ______
|| ______
|| ______
|| ______
|-
|| FERTILITÉ
|| ______
|| ______
|| ______
|| PREFER
|-
|| '''FERTILISATION'''
|| ______
|| ______
|| ______
|| ______
|-
|| N-EXTRACTIONS-Ue / Ha
|| ue/ha
|| 150,0
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-Ue / Ha
|| ue/ha
|| 70,0
|| ______
|| ______
|-
|| K-EXTRACTIONS-UE / Ha
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| N-EXTRACTIONS-UE / TONNES
|| ue/tm
|| 7,5
|| ______
|| ______
|-
|| P-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 3,5
|| ______
|| ______
|-
|| K-EXTRACTIONS-KG-UE / TONNES
|| ue/tm
|| 15,0
|| ______
|| ______
|-
|| ENGRAIS-haute (UF Kg / Ha)
|| ue/ha
|| 200,0
|| ______
|| ______
|-
|| ENGRAIS-moyenne (UF Kg / Ha)
|| ue/ha
|| 250,0
|| ______
|| ______
|-
|| ENGRAIS N-bas(Kg-UF / Ha)
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| ENGRAIS P haute (UF Kg / Ha)
|| ue/ha
|| 60,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Ha)
|| ue/ha
|| 90,0
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Ha)
|| ue/ha
|| 120,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (UF Kg / Ha)
|| ue/ha
|| 30,0
|| ______
|| ______
|-
|| ENGRAIS K-moyenne (Kg-UF / Ha)
|| ue/ha
|| 165,0
|| ______
|| ______
|-
|| ENGRAIS K-bas (Kg-UF / Ha)
|| ue/ha
|| 300,0
|| ______
|| ______
|-
|| ENGRAIS N-haute (Kg-UF / Tm)
|| ue/tm
|| 10,0
|| ______
|| ______
|-
|| ENGRAIS N-moyenne (Kg-UF / Tm)
|| ue/tm
|| 12,5
|| ______
|| ______
|-
|| ENGRAIS N-bas (Kg-UF / Tm)
|| ue/tm
|| 15,0
|| ______
|| ______
|-
|| ENGRAIS P-haut (Kg-UF / Tm)
|| ue/tm
|| 3,0
|| ______
|| ______
|-
|| ENGRAIS P-moyenne (Kg-UF / Tm)
|| ue/tm
|| 4,5
|| ______
|| ______
|-
|| ENGRAIS P-bas (Kg-UF / Tm)
|| ue/tm
|| 6,0
|| ______
|| ______
|-
|| ENGRAIS K-haut (Kg-UF / Tm)
|| ue/tm
|| 1,5
|| ______
|| ______
|-
|| ENGRAIS K-moyenneKg-UF / Tm)
|| ue/tm
|| 8,3
|| ______
|| ______
|-
|| ENGRAIS K-bas(Kg-UF / Tm)
|| ue/tm
|| 15,0
|| ______
|| ______
|-
|| '''TECHNIQUES DE CULTURE
|| ______
|| ______
|| ______
|| ______
|-
|| SEMIS-PLANTATION
|| ______
|| ______
|| ______
|| ______
|-
|| GROOVE, LIGNES DE DISTANCE
|| m
|| 1,0
|| 0,8-1,2
|| ______
|-
|| GROOVE, PLANTE DISTANCE cm
|| m
|| 0,8
|| ______
|| ______
|-
|| N °-PLANTES-TUBERCULES/HA.
|| plantes/ha
|| 9.000,0
|| ______
|| ______
|-
|| TRAVAIL DE COLLECTE
|| ______
|| ______
|| ______
|| ______
|-
|| MOYENNE PRODUCTION Tm./HA.
|| tonne/ha
|| 15,0
|| 12-18
|| ______
|-
|| Temps INTERPASES
|| jours
|| 3,0
|| ______
|| ______
|-
|| temps durée Plantation
|| années
|| 2,0
|| ______
|| ______
|-
|| POST-RÉCOLTE-MARKETING
|| ______
|| ______
|| ______
|| ______
|-
|| TEMPÉRATURE DE STOCKAGE
|| Cº
|| 1,0
|| ______
|| ______
|-
|| % HUMIDITÉ DE STOCKAGE
|| %
|| ______
|| 90-95
|| ______
|-
|| TEMPS STOCKAGE AU FROID
|| jours
|| 21,0
|| ______
|| ______
|-
|| '''COMPOSITION ALIMENTAIRE'''
|| ______
|| ______
|| ______
|| ______
|-
|| Eau -Produit Frais
|| gr
|| 85,0
|| ______
|| ______
|-
|| matière sèche - produit Frais
|| gr
|| 15,0
|| ______
|| ______
|-
|| Énergie-produits frais
|| kcal
|| 53,0
|| ______
|| ______
|-
|| Énergie-matière sec
|| kcal
|| 353,3
|| ______
|| ______
|-
|| Hydrates de carbone-Producto Frais
|| gr
|| 10,2
|| ______
|| ______
|-
|| Hydrates de carbone-matière sec
|| %
|| 68,0
|| ______
|| ______
|-
|| SUCRE-produits frais
|| gr
|| 1,0
|| ______
|| ______
|-
|| SUCRE-matière sec
|| %
|| 6,7
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - Produits frais
|| gr
|| 5,4
|| ______
|| ______
|-
|| fibre DIÉTÉTIQUE - matière sec
|| %
|| 36,0
|| ______
|| ______
|-
|| MATIÈRES GRASSES-Produits frais
|| gr
|| 0,3
|| ______
|| ______
|-
|| MATIÈRES GRASSES- matière sec
|| %
|| 2,3
|| ______
|| ______
|-
|| protéines-Produits frais
|| gr
|| 2,9
|| ______
|| ______
|-
|| protéines- matière sec
|| %
|| 19,3
|| ______
|| ______
|-
|}
{{AutoCat}}
tju1nq42a94lh7s9z3z61dky9n2g8bg
Le mouvement Wikimédia/L'utopie Wikimédia
0
79253
764221
764220
2026-04-21T12:05:08Z
Lionel Scheepmans
20012
764221
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Au fil du temps, Wikipédia fut perçu comme une utopie en marche<ref>{{Article|langue=|prénom1=Christian|nom1=Vandendorpe|titre=Le phénomène Wikipédia: une utopie en marche|périodique=Le Débat|volume=148|numéro=1|éditeur=Gallimard|date=2008|issn=0246-2346|pages=17}}.</ref>, puis comme une utopie réalisée<ref>{{Ouvrage|prénom1=Théo|nom1=Henri|directeur1=|titre=Wikipédia : une utopie réalisée ?|lieu=Université de Poitier|date=juillet 2013|pages totales=98|lire en ligne=https://web.archive.org/web/20211103122912/https://www.seies.net/sites/theo/doc/HENRI_theo_-_master_1_-_memoire.pdf}}.</ref>, et finalement comme la dernière utopie collective du Web<ref>{{Lien web|langue=fr-FR|nom1=Dupont-Besnard|prénom1=Marcus|titre=Wikipédia, la dernière utopie collective du web ?|url=https://web.archive.org/web/20250516050814/https://www.numerama.com/tech/805447-wikipedia-la-derniere-utopie-collective-du-web.html|site=Numerama|date=2021-12-29|consulté le=2025-12-21}}</ref>. Mais qu'en est-il de l'ensemble du mouvement Wikimédia ? Pour nous aider à comprendre ce qui se passe dans la dimension numérique de ce mouvement, voici une métaphore qui décrit un quartier établi au sein de la ville « Espace Web ». Dans cette ville imaginaire, Internet représenterait alors le réseau routier, pendant que des serveurs informatiques feraient office de bâtiments, tandis que les pages web qu'ils hébergent représenteraient les différentes pièces habitables de ces édifices.
Le quartier Wikimédia rassemblerait ainsi plus d’un millier de bâtiments. Au sein de ceux-ci et à l’exception de quelques lieux administratifs, chaque pièce peut être visitée gratuitement et même modifiée au niveau de son contenu. On peut dès lors y ajouter de nouvelles choses, telles que du texte, des photos, des vidéos ou des documents sonores, et changer ou supprimer ce qui a été créé ou modifié par d’autres. Tout cela, bien sûr, dans le but de rendre ces endroits plus esthétiques et plus authentiques et en tenant compte des différentes idées et des éventuelles oppositions de point de vue concernant les aménagements. Pour faciliter l'entente entre les personnes qui s'investissent dans ces changements, chaque pièce des bâtiments Wikimédia possède un espace annexe dédié à la discussion.
Dans la plupart des bâtiments Wikimédia, une personne malintentionnée peut même faire disparaitre tout le contenu d'une pièce. Néanmoins, dans la seconde qui suit, un robot remettra tout en place, avant de transmettre un message concernant le traitement du vandalisme. Lorsqu'une action plus discrète n'est pas détectée par un robot, c'est alors quelqu'un qui surveille la pièce qui prendra le relais pour annuler les changements malveillants et contacter la personne responsable. En cas de multirécidive, celle-ci peut se voir privée de sa capacité de modifier les pièces, soit dans le bâtiment vandalisé, soit dans tout le quartier quand cela se justifie. Après discussion, cette sanction sera mise en application par un administrateur ou une administratrice bénévole, choisi ou choisie par l'ensemble des autres bénévoles qui prennent soin des bâtiments.
[[Fichier:The Digital City, Riyadh 191957.jpg|vignette|<small>Figure 3. Photo de la ''Digital City'' de [[w:Riyad|Riyadh]] et son aspect visuel en lien avec la métaphore du quartier Wikimédia.</small>|300x300px]]
On comprend donc que tout le monde peut enrichir, mais également surveiller et protéger les richesses partagées dans le quartier Wikimédia. Il suffit pour cela de rejoindre le mouvement en se créant un compte. Cela permet de profiter de nombreux outils, dont notamment un système qui envoie des notifications dès qu'une pièce que l'on veut surveiller est modifiée.
Pour créer ce compte, pas besoin de fournir une adresse ou un numéro de téléphone. Les seules informations personnelles indispensables au bon fonctionnement du quartier Wikimédia sont les [[w:Adresses_IP|adresses IP]] des ordinateurs connectés. Car contrairement à ce qui se passe dans les quartiers commerciaux de la grande ville numérique, tels que les [[w:GAFAM|GAFAM]], [[w:NATU_(Netflix,_Airbnb,_Tesla_et_Uber)|NATU]], [[w:BATX|BATX]] ou autres, aucune des informations récoltées lors de la visite des bâtiments. Wikimédia ne collecte effectivement aucune donnée dans le but de les vendre à des personnes qui en feront l'exploitation.
Même les adresses IP enregistrées par le système ne sont pas visibles par les autres visiteurs. Elles sont remplacées par les noms et les pseudonymes fournis lors de la création des comptes, ou masquées par des comptes temporaires pour les modifications faites par des personnes non connectées. Seules quelques personnes accréditées par la communauté pour effectuer des contrôles d’usurpation d’identité ont accès à ces informations<ref>{{Lien web|auteur=MédiaWiki|titre=Produit de confiance et de sécurité/Comptes temporaires|url=https://web.archive.org/web/20250813140004/https://www.mediawiki.org/wiki/Trust_and_Safety_Product/Temporary_Accounts/fr}}.</ref>. C’est là une précaution nécessaire au bon déroulement des votes qui succèdent parfois aux recherches de [[w:Consensus|consensus]] concernant l'aménagement du quartier Wikimédia.
Dans cette ville numérique que constituerait l'espace web, Wikimédia apparait ainsi comme le plus grand quartier dédié au partage de la connaissance. Tout d'abord, il y a les plus de 350 bâtiments [[w:Wikipédia:Accueil_principal|Wikipédia]], chacun dédié à une version linguistique de l'encyclopédie. Ensuite, juste à côté et toujours séparés en versions linguistiques, se trouvent les bibliothèques [[:en:fr:accueil|Wikilivres]] et [[s:fr:Wikisource:Accueil|Wikisource]], les bâtiments lexicaux multilingues [[wikt:fr:Wiktionnaire:Page_d’accueil|Wiktionnaire]], le centre journalistique [[n:fr:accueil|Wikinews]], le centre pédagogique et de recherche [[v:fr:accueil|Wikiversité]], le centre d'informations touristique [[voy:fr:accueil|Wikivoyage]], le répertoire des êtres vivants [[species:main page|Wikispecies]] et enfin l'institut des citations d’auteurs [[q:fr:accueil|Wikiquote]]. Cela sans oublier qu'à deux pas de là se situent le musée médiatique [[commons:main page|Wikimedia Commons]] et [[wikidata:wikidata:main_page|Wikidata]] qui constitue la plus grande banque d’informations structurées au monde. Deux bâtiments dont l'une des fonctions principales communes est d’enrichir les pièces situées dans les autres buildings du quartier Wikimédia.
Dans tous ces immeubles, il arrive souvent que plus de la moitié des étages soient uniquement attribués à l'organisation des activités qui s'y déroulent. Chaque bâtiment peut aussi compter sur le soutien d'autres édifices tels que [[mw:main page|MediaWiki]], [[wikitech:Main_Page|Wikitech]], [[w:fr:phabricator|Phabricator]], qui sont trois lieux entièrement dédiés aux maintenances techniques sur l'ensemble du quartier. Quant aux aspects administratifs, c'est dans le bâtiment [[metawiki:main page|Méta-Wiki]] que s'opère la gouvernance générale du quartier et dans le bâtiment [[otrswiki:Main page|Wikimedia VRT]] que le traitement des courriers est effectué. À la suite de quoi, il ne reste plus qu'à citer le bâtiment ''[[outreach:main page|Wikimedia outreach]],'' pour des initiatives de sensibilisation au mouvement, et le bâtiment [https://diff.wikimedia.org Diff Wikimedia], pour des publications d'articles à son sujet.
Le plus utopique dans tout cela, c'est qu'en dehors de certains aspects techniques, tous ces bâtiments sont exclusivement régis par des communautés bénévoles et toujours prêtes à accueillir de nouveaux membres. Les seuls immeubles du quartier qui diffèrent de ce principe sont les bâtiments vitrines de la Fondation Wikimédia et des autres associations Wikimédia qui engagent du personnel. Quant au conseil d'administration de la Fondation, il possède, lui aussi, son propre bâtiment, dont la modification des pièces est réservée à ces élus et aux employés qui les aident dans leurs tâches. Cela pour garantir l'officialité de ce qui s'y passe.
Finalement et face à tant d'utopies, il est tentant de se demander comment tout cela fut rendu possible. La réponse à cette question n'est pas courte. Elle demande de parcourir tout un pan de l'histoire de la révolution numérique, depuis la [[w:Contre-culture_des_années_1960|contre-culture des années 1960]] jusqu'à nos jours. On y découvre alors que les pionniers du réseau Internet et de ses applications étaient des chercheurs et étudiants en informatique fortement influencés par les mouvements idéologiques mondiaux. Ceux qui, entre autres, ont contribué à l'avènement de [[w:mai_68|mai 68]] en France. De toutes ces impulsions naîtra en effet la philosophie de partage, de liberté, de décentralisation et ce mode d’organisation tout à fait spécifique, dont a hérité le mouvement Wikimédia.
Cela commence par [[w:Internet|Internet]], un réseau mondial de communication en libre accès, puis par le développement du ''[[w:World_Wide_Web|World Wide Web]]'', qui a grandement simplifié les interactions humaines à l’échelle planétaire. Cela se poursuit ensuite par l'arrivée des sites web que l'on peut modifier à l'aide d’un simple navigateur et qui furent à l'origine de ce que l'on a appelé le [[w:Web_2.0|Web 2.0]]. Or, parmi ces logiciels se trouvent les [[w:fr:Moteur de Wiki|moteurs de Wiki]], dont le plus puissant d’entre eux, [[w:MediaWiki|MediaWiki]], est un [[Logiciels libres|logiciel libre]] développé par la Fondation Wikimédia. Le moment est donc venu d'en savoir un peu plus sur ces logiciels et sur le [[w:Mouvement_du_logiciel_libre|mouvement du logiciel libre]] qui s'est constitué tout autour.{{AutoCat}}
nek4hiqqiz0t10n9fww0q0tfulgr65h
764222
764221
2026-04-21T13:21:07Z
Lionel Scheepmans
20012
764222
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Au fil du temps, Wikipédia fut perçu comme une utopie en marche<ref>{{Article|langue=|prénom1=Christian|nom1=Vandendorpe|titre=Le phénomène Wikipédia: une utopie en marche|périodique=Le Débat|volume=148|numéro=1|éditeur=Gallimard|date=2008|issn=0246-2346|pages=17}}.</ref>, puis comme une utopie réalisée<ref>{{Ouvrage|prénom1=Théo|nom1=Henri|directeur1=|titre=Wikipédia : une utopie réalisée ?|lieu=Université de Poitier|date=juillet 2013|pages totales=98|lire en ligne=https://web.archive.org/web/20211103122912/https://www.seies.net/sites/theo/doc/HENRI_theo_-_master_1_-_memoire.pdf}}.</ref>, et finalement comme la dernière utopie collective du Web<ref>{{Lien web|langue=fr-FR|nom1=Dupont-Besnard|prénom1=Marcus|titre=Wikipédia, la dernière utopie collective du web ?|url=https://web.archive.org/web/20250516050814/https://www.numerama.com/tech/805447-wikipedia-la-derniere-utopie-collective-du-web.html|site=Numerama|date=2021-12-29|consulté le=2025-12-21}}</ref>. Mais qu'en est-il de l'ensemble du mouvement Wikimédia ? Pour nous aider à comprendre ce qui se passe dans la dimension numérique de ce mouvement, voici une métaphore qui décrit un quartier établi au sein de la ville « Espace Web ». Dans cette ville imaginaire, Internet représenterait alors le réseau routier, pendant que des serveurs informatiques feraient office de bâtiments, tandis que les pages web qu'ils hébergent représenteraient les différentes pièces habitables de ces édifices.
Le quartier Wikimédia rassemblerait ainsi plus d’un millier de bâtiments. Au sein de ceux-ci et à l’exception de quelques lieux administratifs, chaque pièce peut être visitée gratuitement et même modifiée au niveau de son contenu. On peut dès lors y ajouter de nouvelles choses, telles que du texte, des photos, des vidéos ou des documents sonores, et changer ou supprimer ce qui a été créé ou modifié par d’autres. Tout cela, bien sûr, dans le but de rendre ces endroits plus esthétiques et plus authentiques et en tenant compte des différentes idées et des éventuelles oppositions de point de vue concernant les aménagements. Pour faciliter l'entente entre les personnes qui s'investissent dans ces changements, chaque pièce des bâtiments Wikimédia possède un espace annexe dédié à la discussion.
Dans la plupart des bâtiments Wikimédia, une personne malintentionnée peut même faire disparaitre tout le contenu d'une pièce. Néanmoins, dans la seconde qui suit, un robot remettra tout en place, avant de transmettre un message concernant le traitement du vandalisme. Lorsqu'une action plus discrète n'est pas détectée par un robot, c'est alors quelqu'un qui surveille la pièce qui prendra le relais pour annuler les changements malveillants et contacter la personne responsable. En cas de multirécidive, celle-ci peut se voir privée de sa capacité de modifier les pièces, soit dans le bâtiment vandalisé, soit dans tout le quartier quand cela se justifie. Après discussion, cette sanction sera mise en application par un administrateur ou une administratrice bénévole, choisi ou choisie par l'ensemble des autres bénévoles qui prennent soin des bâtiments.
[[Fichier:The Digital City, Riyadh 191957.jpg|vignette|<small>Figure 3. Photo de la ''Digital City'' de [[w:Riyad|Riyadh]] et son aspect visuel en lien avec la métaphore du quartier Wikimédia.</small>|300x300px]]
On comprend donc que tout le monde peut enrichir, mais également surveiller et protéger les richesses partagées dans le quartier Wikimédia. Il suffit pour cela de rejoindre le mouvement en se créant un compte. Cela permet de profiter de nombreux outils, dont notamment un système qui envoie des notifications, dès qu'une pièce que l'on veut surveiller est modifiée.
Pour créer ce compte, pas besoin de fournir une adresse ou un numéro de téléphone. Les seules informations personnelles indispensables au bon fonctionnement du quartier Wikimédia sont les [[w:Adresses_IP|adresses IP]] des visiteurs. Lors des visites et contrairement à ce qui se passe dans les quartiers commerciaux de la grande ville numérique, tels que les [[w:GAFAM|GAFAM]], [[w:NATU_(Netflix,_Airbnb,_Tesla_et_Uber)|NATU]], [[w:BATX|BATX]], le quartier Wikimédia ne récolte et ne vend aucune donnée à des fins d'exploitation.
Même les adresses IP enregistrées par le système ne sont pas visibles par les autres visiteurs. Elles sont remplacées par les noms et les pseudonymes fournis lors de la création des comptes, ou masquées par des comptes temporaires pour les modifications faites par des personnes non connectées. Seules quelques personnes accréditées par la communauté pour effectuer des contrôles d’usurpation d’identité ont accès à ces informations<ref>{{Lien web|auteur=MédiaWiki|titre=Produit de confiance et de sécurité/Comptes temporaires|url=https://web.archive.org/web/20250813140004/https://www.mediawiki.org/wiki/Trust_and_Safety_Product/Temporary_Accounts/fr}}.</ref>. C’est là une précaution nécessaire au bon déroulement des votes qui succèdent parfois aux recherches de [[w:Consensus|consensus]] concernant l'aménagement du quartier Wikimédia.
Dans cette ville numérique que constituerait l'espace web, Wikimédia apparait ainsi comme le plus grand quartier dédié au partage de la connaissance. Tout d'abord, il y a les plus de 350 bâtiments [[w:Wikipédia:Accueil_principal|Wikipédia]], chacun dédié à une version linguistique de l'encyclopédie. Puis, toujours séparés en versions linguistiques, on trouve ensuite les bibliothèques [[:en:fr:accueil|Wikilivres]] et [[s:fr:Wikisource:Accueil|Wikisource]], les bâtiments lexicaux multilingues [[wikt:fr:Wiktionnaire:Page_d’accueil|Wiktionnaire]], le centre journalistique [[n:fr:accueil|Wikinews]], le centre pédagogique et de recherche [[v:fr:accueil|Wikiversité]], le centre d'informations touristique [[voy:fr:accueil|Wikivoyage]], le répertoire des êtres vivants [[species:main page|Wikispecies]] et enfin l'institut des citations d’auteurs [[q:fr:accueil|Wikiquote]]. Cela sans oublier le musée médiatique [[commons:main page|Wikimedia Commons]] et la banque [[wikidata:wikidata:main_page|Wikidata]], reconnue comme étant la plus grande banque d’informations structurées au monde. Deux bâtiments dont l'une des fonctions principales communes est d’enrichir les pièces situées dans les autres buildings du quartier Wikimédia.
Dans tous ces immeubles, il arrive souvent que plus de la moitié des étages soient uniquement attribués à l'organisation des activités qui s'y déroulent. Chaque bâtiment peut aussi compter sur le soutien d'autres édifices tels que [[mw:main page|MediaWiki]], [[wikitech:Main_Page|Wikitech]], [[w:fr:phabricator|Phabricator]], qui sont trois lieux entièrement dédiés aux maintenances techniques sur l'ensemble du quartier. Concernant les aspects administratifs, c'est dans le bâtiment [[metawiki:main page|Méta-Wiki]] que s'opère la gouvernance générale du quartier, alors que les courriers adressés à ce dernier sont traités en première ligne dans le bâtiment [[otrswiki:Main page|Wikimedia VRT]]. À la suite de quoi, il ne reste plus qu'à citer le bâtiment ''[[outreach:main page|Wikimedia outreach]],'' pour des initiatives de sensibilisation, et le bâtiment du journal [https://diff.wikimedia.org Diff Wikimedia], comme lieu de publication d'actualités sur le mouvement.
En dehors de certains aspects techniques, tous ces bâtiments sont exclusivement régis par des communautés bénévoles, qui sont toujours prêtes à accueillir de nouveaux membres. Les seuls immeubles du quartier qui diffèrent de ce principe sont les bâtiments vitrines de la Fondation Wikimédia et des autres associations Wikimédia qui engagent du personnel. Quant au bâtiment du conseil d'administration de la Fondation, des raisons officielles justifient le fait que la modification de ses pièces est réservée à ces membres et aux employés qui les soutiennent.
Face à tant d'utopies, il est tentant de se demander comment tout cela fut rendu possible. La réponse à cette question n'est pas courte. Elle demande de parcourir tout un pan de l'histoire de la révolution numérique, depuis la [[w:Contre-culture_des_années_1960|contre-culture des années 1960]] jusqu'à nos jours. On y découvre alors que les pionniers du réseau Internet et de ses applications étaient des chercheurs et étudiants en informatique fortement influencés par les mouvements idéologiques mondiaux. Ceux qui, entre autres, ont contribué à l'avènement de [[w:mai_68|mai 68]] en France. De toutes ces impulsions naîtra en effet la philosophie de partage, de liberté, de décentralisation et ce mode d’organisation tout à fait spécifique, dont a hérité le mouvement Wikimédia.
Cela commence par [[w:Internet|Internet]], un réseau mondial de communication en libre accès, puis par le développement du ''[[w:World_Wide_Web|World Wide Web]]'', qui a grandement simplifié les interactions humaines à l’échelle planétaire. Cela se poursuit ensuite par l'arrivée des sites web que l'on peut modifier à l'aide d’un simple navigateur et qui furent à l'origine de ce que l'on a appelé le [[w:Web_2.0|Web 2.0]]. Or, parmi ces logiciels se trouvent les [[w:fr:Moteur de Wiki|moteurs de Wiki]], dont le plus puissant d’entre eux, [[w:MediaWiki|MediaWiki]], est un [[Logiciels libres|logiciel libre]] développé par la Fondation Wikimédia. Le moment est donc venu d'en savoir un peu plus sur ces logiciels et sur le [[w:Mouvement_du_logiciel_libre|mouvement du logiciel libre]] qui s'est constitué tout autour.{{AutoCat}}
f1455a0vixisgx9hmeut5rmdn07z726
764223
764222
2026-04-21T13:29:41Z
Lionel Scheepmans
20012
764223
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Au fil du temps, Wikipédia fut perçu comme une utopie en marche<ref>{{Article|langue=|prénom1=Christian|nom1=Vandendorpe|titre=Le phénomène Wikipédia: une utopie en marche|périodique=Le Débat|volume=148|numéro=1|éditeur=Gallimard|date=2008|issn=0246-2346|pages=17}}.</ref>, puis comme une utopie réalisée<ref>{{Ouvrage|prénom1=Théo|nom1=Henri|directeur1=|titre=Wikipédia : une utopie réalisée ?|lieu=Université de Poitier|date=juillet 2013|pages totales=98|lire en ligne=https://web.archive.org/web/20211103122912/https://www.seies.net/sites/theo/doc/HENRI_theo_-_master_1_-_memoire.pdf}}.</ref>, et finalement comme la dernière utopie collective du Web<ref>{{Lien web|langue=fr-FR|nom1=Dupont-Besnard|prénom1=Marcus|titre=Wikipédia, la dernière utopie collective du web ?|url=https://web.archive.org/web/20250516050814/https://www.numerama.com/tech/805447-wikipedia-la-derniere-utopie-collective-du-web.html|site=Numerama|date=2021-12-29|consulté le=2025-12-21}}</ref>. Mais qu'en est-il de l'ensemble du mouvement Wikimédia ? Pour nous aider à comprendre ce qui se passe dans la dimension numérique de ce mouvement, voici une métaphore qui décrit un quartier établi au sein de la ville « Espace Web ». Dans cette ville imaginaire, Internet représenterait alors le réseau routier, pendant que des serveurs informatiques feraient office de bâtiments, tandis que les pages web qu'ils hébergent représenteraient les différentes pièces habitables de ces édifices.
Le quartier Wikimédia rassemblerait ainsi plus d’un millier de bâtiments. Au sein de ceux-ci et à l’exception de quelques lieux administratifs, chaque pièce peut être visitée gratuitement et même modifiée au niveau de son contenu. On peut dès lors y ajouter de nouvelles choses, telles que du texte, des photos, des vidéos ou des documents sonores, et changer ou supprimer ce qui a été créé ou modifié par d’autres. Tout cela, bien sûr, dans le but de rendre ces endroits plus esthétiques et plus authentiques et en tenant compte des différentes idées et des éventuelles oppositions de point de vue concernant les aménagements. Pour faciliter l'entente entre les personnes qui s'investissent dans ces changements, chaque pièce des bâtiments Wikimédia possède un espace annexe dédié à la discussion.
Dans la plupart des bâtiments Wikimédia, une personne malintentionnée peut même faire disparaitre tout le contenu d'une pièce. Néanmoins, dans la seconde qui suit, un robot remettra tout en place, avant de transmettre un message concernant le traitement du vandalisme. Lorsqu'une action plus discrète n'est pas détectée par un robot, c'est alors quelqu'un qui surveille la pièce qui prendra le relais pour annuler les changements malveillants et contacter la personne responsable. En cas de multirécidive, celle-ci peut se voir privée de sa capacité de modifier les pièces, soit dans le bâtiment vandalisé, soit dans tout le quartier quand cela se justifie. Après discussion, cette sanction sera mise en application par un administrateur ou une administratrice bénévole, choisi ou choisie par l'ensemble des autres bénévoles qui prennent soin des bâtiments.
[[Fichier:The Digital City, Riyadh 191957.jpg|vignette|<small>Figure 3. Photo de la ''Digital City'' de [[w:Riyad|Riyadh]] et son aspect visuel en lien avec la métaphore du quartier Wikimédia.</small>|300x300px]]
On comprend donc que tout le monde peut enrichir, mais également surveiller et protéger les richesses partagées dans le quartier Wikimédia. Il suffit pour cela de rejoindre le mouvement en se créant un compte. Cela permet de profiter de nombreux outils, dont notamment un système qui envoie des notifications, dès qu'une pièce que l'on veut surveiller est modifiée.
Pour créer ce compte, pas besoin de fournir une adresse ou un numéro de téléphone. Les seules informations personnelles indispensables au bon fonctionnement du quartier Wikimédia sont les [[w:Adresses_IP|adresses IP]] des visiteurs. Lors des visites et contrairement à ce qui se passe dans les quartiers commerciaux de la grande ville numérique, tels que les [[w:GAFAM|GAFAM]], [[w:NATU_(Netflix,_Airbnb,_Tesla_et_Uber)|NATU]], [[w:BATX|BATX]], le quartier Wikimédia ne récolte et ne vend aucune donnée à des fins d'exploitation.
Même les adresses IP enregistrées par le système ne sont pas visibles par les autres visiteurs. Elles sont remplacées par les noms et les pseudonymes fournis lors de la création des comptes, ou masquées par des comptes temporaires pour les modifications faites par des personnes non connectées. Seules quelques personnes accréditées par la communauté pour effectuer des contrôles d’usurpation d’identité ont accès à ces informations<ref>{{Lien web|auteur=MédiaWiki|titre=Produit de confiance et de sécurité/Comptes temporaires|url=https://web.archive.org/web/20250813140004/https://www.mediawiki.org/wiki/Trust_and_Safety_Product/Temporary_Accounts/fr}}.</ref>. C’est là une précaution nécessaire au bon déroulement des votes qui succèdent parfois aux recherches de [[w:Consensus|consensus]] concernant l'aménagement du quartier Wikimédia.
Dans cette ville numérique que constituerait l'espace web, Wikimédia apparait ainsi comme le plus grand quartier dédié au partage de la connaissance. Tout d'abord, il y a les plus de 350 bâtiments [[w:Wikipédia:Accueil_principal|Wikipédia]], chacun dédié à une version linguistique de l'encyclopédie. Puis, toujours séparés en versions linguistiques, on trouve ensuite les bibliothèques [[:en:fr:accueil|Wikilivres]] et [[s:fr:Wikisource:Accueil|Wikisource]], les bâtiments lexicaux multilingues [[wikt:fr:Wiktionnaire:Page_d’accueil|Wiktionnaire]], le centre journalistique [[n:fr:accueil|Wikinews]], le centre pédagogique et de recherche [[v:fr:accueil|Wikiversité]], le centre d'informations touristique [[voy:fr:accueil|Wikivoyage]], le répertoire des êtres vivants [[species:main page|Wikispecies]] et enfin l'institut des citations d’auteurs [[q:fr:accueil|Wikiquote]]. Cela sans oublier le musée médiatique [[commons:main page|Wikimedia Commons]] et la banque [[wikidata:wikidata:main_page|Wikidata]], reconnue comme étant la plus grande banque d’informations structurées au monde. Deux bâtiments dont l'une des fonctions principales communes est d’enrichir les pièces situées dans les autres buildings du quartier Wikimédia.
Dans tous ces immeubles, il arrive souvent que plus de la moitié des étages soient uniquement attribués à l'organisation des activités qui s'y déroulent. Chaque bâtiment peut aussi compter sur le soutien d'autres édifices tels que [[mw:main page|MediaWiki]], [[wikitech:Main_Page|Wikitech]], [[w:fr:phabricator|Phabricator]], qui sont trois lieux entièrement dédiés aux maintenances techniques sur l'ensemble du quartier. Concernant les aspects administratifs, c'est dans le bâtiment [[metawiki:main page|Méta-Wiki]] que s'opère la gouvernance générale du quartier, alors que les courriers adressés à ce dernier sont traités en première ligne dans le bâtiment [[otrswiki:Main page|Wikimedia VRT]]. À la suite de quoi, il ne reste plus qu'à citer le bâtiment ''[[outreach:main page|Wikimedia outreach]],'' pour des initiatives de sensibilisation, et le bâtiment du journal [https://diff.wikimedia.org Diff Wikimedia], comme lieu de publication d'actualités sur le mouvement.
En dehors de certains aspects techniques, tous ces bâtiments sont exclusivement régis par des communautés bénévoles, qui sont toujours prêtes à accueillir de nouveaux membres. Les seuls immeubles du quartier qui diffèrent de ce principe sont les bâtiments vitrines de la Fondation Wikimédia et des autres associations Wikimédia qui engagent du personnel. Quant au bâtiment du conseil d'administration de la Fondation, des raisons officielles justifient le fait que la modification de ses pièces est réservée à ces membres et aux employés qui les soutiennent.
Face à tant d'utopies, il est tentant de se demander comment tout cela fut rendu possible. La réponse à cette question n'est pas courte. Elle demande de parcourir tout un pan de l'histoire de la révolution numérique, depuis la [[w:Contre-culture_des_années_1960|contre-culture des années 1960]] jusqu'à nos jours. On y découvre alors que les pionniers du réseau Internet étaient des chercheurs et étudiants en informatique fortement influencés par de nouvelles idéologies, telles que celles qui furent à la source des évènements de [[w:mai_68|mai 68]] en France. C'est donc de là que naîtra la philosophie de partage, de liberté, de décentralisation et ce mode d’organisation tout à fait spécifique, que l'on observe aujourd'hui au sein du mouvement Wikimédia.
Cela commence par [[w:Internet|Internet]], un réseau mondial de communication en libre accès, puis par le développement du ''[[w:World_Wide_Web|World Wide Web]]'', qui a grandement simplifié les interactions humaines à l’échelle planétaire. Cela se poursuit ensuite par l'arrivée des sites web que l'on peut modifier à l'aide d’un simple navigateur et qui furent à l'origine de ce que l'on a appelé le [[w:Web_2.0|Web 2.0]]. Or, parmi ces logiciels se trouvent les [[w:fr:Moteur de Wiki|moteurs de Wiki]], dont le plus puissant d’entre eux, [[w:MediaWiki|MediaWiki]], est un [[Logiciels libres|logiciel libre]] développé par la Fondation Wikimédia. Le moment est donc venu d'en savoir un peu plus sur ces logiciels et sur le [[w:Mouvement_du_logiciel_libre|mouvement du libre]] qui s'est constitué tout autour.{{AutoCat}}
4vl0c7acmjut755tp9ay2dfl22p5e5j
764224
764223
2026-04-21T13:51:18Z
Lionel Scheepmans
20012
764224
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Au fil du temps, Wikipédia fut perçu comme une utopie en marche<ref>{{Article|langue=|prénom1=Christian|nom1=Vandendorpe|titre=Le phénomène Wikipédia: une utopie en marche|périodique=Le Débat|volume=148|numéro=1|éditeur=Gallimard|date=2008|issn=0246-2346|pages=17}}.</ref>, puis comme une utopie réalisée<ref>{{Ouvrage|prénom1=Théo|nom1=Henri|directeur1=|titre=Wikipédia : une utopie réalisée ?|lieu=Université de Poitier|date=juillet 2013|pages totales=98|lire en ligne=https://web.archive.org/web/20211103122912/https://www.seies.net/sites/theo/doc/HENRI_theo_-_master_1_-_memoire.pdf}}.</ref>, et finalement comme la dernière utopie collective du Web<ref>{{Lien web|langue=fr-FR|nom1=Dupont-Besnard|prénom1=Marcus|titre=Wikipédia, la dernière utopie collective du web ?|url=https://web.archive.org/web/20250516050814/https://www.numerama.com/tech/805447-wikipedia-la-derniere-utopie-collective-du-web.html|site=Numerama|date=2021-12-29|consulté le=2025-12-21}}</ref>. Mais qu'en est-il de l'ensemble du mouvement Wikimédia ? Pour nous aider à comprendre ce qui se passe dans la dimension numérique de ce mouvement, voici une métaphore qui décrit un quartier établi au sein de la ville « Espace Web ». Dans cette ville imaginaire, Internet représenterait alors le réseau routier, pendant que des serveurs informatiques feraient office de bâtiments, tandis que les pages web qu'ils hébergent représenteraient les différentes pièces habitables de ces édifices.
Le quartier Wikimédia rassemblerait ainsi plus d’un millier de bâtiments. Au sein de ceux-ci et à l’exception de quelques lieux administratifs, chaque pièce peut être visitée gratuitement et même modifiée au niveau de son contenu. On peut dès lors y ajouter de nouvelles choses, telles que du texte, des photos, des vidéos ou des documents sonores, et changer ou supprimer ce qui a été créé ou modifié par d’autres. Tout cela, bien sûr, dans le but de rendre ces endroits plus esthétiques et plus authentiques et en tenant compte des différentes idées et des éventuelles oppositions de point de vue concernant les aménagements. Pour faciliter l'entente entre les personnes qui s'investissent dans ces changements, chaque pièce des bâtiments Wikimédia possède un espace annexe dédié à la discussion.
Dans la plupart des bâtiments Wikimédia, une personne malintentionnée peut même faire disparaitre tout le contenu d'une pièce. Néanmoins, dans la seconde qui suit, un robot remettra tout en place, avant de transmettre un message concernant le traitement du vandalisme. Lorsqu'une action plus discrète n'est pas détectée par un robot, c'est alors quelqu'un qui surveille la pièce qui prendra le relais pour annuler les changements malveillants et contacter la personne responsable. En cas de multirécidive, celle-ci peut se voir privée de sa capacité de modifier les pièces, soit dans le bâtiment vandalisé, soit dans tout le quartier quand cela se justifie. Après discussion, cette sanction sera mise en application par un administrateur ou une administratrice bénévole, choisi ou choisie par l'ensemble des autres bénévoles qui prennent soin des bâtiments.
[[Fichier:The Digital City, Riyadh 191957.jpg|vignette|<small>Figure 3. Photo de la ''Digital City'' de [[w:Riyad|Riyadh]] et son aspect visuel en lien avec la métaphore du quartier Wikimédia.</small>|300x300px]]
On comprend donc que tout le monde peut enrichir, mais également surveiller et protéger les richesses partagées dans le quartier Wikimédia. Il suffit pour cela de rejoindre le mouvement en se créant un compte. Cela permet de profiter de nombreux outils, dont notamment un système qui envoie des notifications, dès qu'une pièce que l'on veut surveiller est modifiée.
Pour créer ce compte, pas besoin de fournir une adresse ou un numéro de téléphone. Les seules informations personnelles indispensables au bon fonctionnement du quartier Wikimédia sont les [[w:Adresses_IP|adresses IP]] des visiteurs. Lors des visites et contrairement à ce qui se passe dans les quartiers commerciaux de la grande ville numérique, tels que les [[w:GAFAM|GAFAM]], [[w:NATU_(Netflix,_Airbnb,_Tesla_et_Uber)|NATU]], [[w:BATX|BATX]], le quartier Wikimédia ne récolte et ne vend aucune donnée à des fins d'exploitation.
Même les adresses IP enregistrées par le système ne sont pas visibles par les autres visiteurs. Elles sont remplacées par les noms et les pseudonymes fournis lors de la création des comptes, ou masquées par des comptes temporaires pour les modifications faites par des personnes non connectées. Seules quelques personnes accréditées par la communauté pour effectuer des contrôles d’usurpation d’identité ont accès à ces informations<ref>{{Lien web|auteur=MédiaWiki|titre=Produit de confiance et de sécurité/Comptes temporaires|url=https://web.archive.org/web/20250813140004/https://www.mediawiki.org/wiki/Trust_and_Safety_Product/Temporary_Accounts/fr}}.</ref>. C’est là une précaution nécessaire au bon déroulement des votes qui succèdent parfois aux recherches de [[w:Consensus|consensus]] concernant l'aménagement du quartier Wikimédia.
Dans cette ville numérique que constituerait l'espace web, Wikimédia apparait ainsi comme le plus grand quartier dédié au partage de la connaissance. Tout d'abord, il y a les plus de 350 bâtiments [[w:Wikipédia:Accueil_principal|Wikipédia]], chacun dédié à une version linguistique de l'encyclopédie. Puis, toujours séparés en versions linguistiques, on trouve ensuite les bibliothèques [[:en:fr:accueil|Wikilivres]] et [[s:fr:Wikisource:Accueil|Wikisource]], les bâtiments lexicaux multilingues [[wikt:fr:Wiktionnaire:Page_d’accueil|Wiktionnaire]], le centre journalistique [[n:fr:accueil|Wikinews]], le centre pédagogique et de recherche [[v:fr:accueil|Wikiversité]], le centre d'informations touristique [[voy:fr:accueil|Wikivoyage]], le répertoire des êtres vivants [[species:main page|Wikispecies]] et enfin l'institut des citations d’auteurs [[q:fr:accueil|Wikiquote]]. Cela sans oublier le musée médiatique [[commons:main page|Wikimedia Commons]] et la banque [[wikidata:wikidata:main_page|Wikidata]], reconnue comme étant la plus grande banque d’informations structurées au monde. Deux bâtiments dont l'une des fonctions principales communes est d’enrichir les pièces situées dans les autres buildings du quartier Wikimédia.
Dans tous ces immeubles, il arrive souvent que plus de la moitié des étages soient uniquement attribués à l'organisation des activités qui s'y déroulent. Chaque bâtiment peut aussi compter sur le soutien d'autres édifices tels que [[mw:main page|MediaWiki]], [[wikitech:Main_Page|Wikitech]], [[w:fr:phabricator|Phabricator]], qui sont trois lieux entièrement dédiés aux maintenances techniques sur l'ensemble du quartier. Concernant les aspects administratifs, c'est dans le bâtiment [[metawiki:main page|Méta-Wiki]] que s'opère la gouvernance générale du quartier, alors que les courriers adressés à ce dernier sont traités en première ligne dans le bâtiment [[otrswiki:Main page|Wikimedia VRT]]. À la suite de quoi, il ne reste plus qu'à citer le bâtiment ''[[outreach:main page|Wikimedia outreach]],'' pour des initiatives de sensibilisation, et le bâtiment du journal [https://diff.wikimedia.org Diff Wikimedia], comme lieu de publication d'actualités sur le mouvement.
En dehors de certains aspects techniques, tous ces bâtiments sont exclusivement régis par des communautés bénévoles, qui sont toujours prêtes à accueillir de nouveaux membres. Les seuls immeubles du quartier qui diffèrent de ce principe sont les bâtiments vitrines de la Fondation Wikimédia et des autres associations Wikimédia qui engagent du personnel. Quant au bâtiment du conseil d'administration de la Fondation, des raisons officielles justifient le fait que la modification de ses pièces est réservée à ces membres et aux employés qui les soutiennent.
Face à tant d'utopies, il devient légitime de vouloir comprendre comment tout cela fut rendu possible. Or, pour répondre à cette question, il faut alors parcourir tout un pan de l'histoire de la révolution numérique, depuis la [[w:Contre-culture_des_années_1960|contre-culture des années 1960]] jusqu'à nos jours. On y découvre que les pionniers du réseau Internet étaient des chercheurs et étudiants en informatique, fortement influencés par de nouvelles idéologies, telles que celles qui furent à la source des évènements de [[w:mai_68|mai 68]] en France. C'est donc de là que naîtra la philosophie de partage, de liberté, de décentralisation et ce mode d’organisation tout à fait spécifique, que l'on observe aujourd'hui au sein du mouvement Wikimédia.
Il y eut tout d'abord la création d'[[w:Internet|Internet]], comme réseau mondial de communication en libre accès, puis le développement du ''[[w:World_Wide_Web|World Wide Web]]'', qui a grandement facilité les interactions humaines à l’échelle planétaire. Par la suite, ce fut l'arrivée du [[w:Web_2.0|Web 2.0]], caractérisé par l'apparition de nouveaux sites web directement modifiables à l'aide d’un simple navigateur. Or, parmi ceux-ci se trouvent les [[w:fr:Moteur de Wiki|moteurs de Wiki]], dont le plus puissant d’entre eux, [[w:MediaWiki|MediaWiki]], est un [[Logiciels libres|logiciel libre]] développé par la Fondation Wikimédia. Le moment est donc venu d'en savoir plus sur ce type de programme informatique, ainsi que sur le [[w:Mouvement_du_logiciel_libre|mouvement du logiciel libre]], qui a fortement influencé la philosophie et les valeurs véhiculées au sein du mouvement Wikimédia.{{AutoCat}}
g3beh1zah1mjsw1phi8ey73ybprer24
Le mouvement Wikimédia/Les platesformes Wiki
0
79271
764400
757342
2026-04-22T10:26:47Z
Lionel Scheepmans
20012
764400
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Un [[w:Wiki|wiki]], ou un [[w:Moteur_de_wiki|moteur de wiki]], est un logiciel que l'on installe sur un serveur informatique pour permettre la création d’un site web éditable et configurable à l’aide d’un simple navigateur. Plus précisément, c’est un [[w:Système_de_gestion_de_contenu|système de gestion de contenu]], dans lequel le code [[Le langage HTML|HTML]], [[Le langage CSS|CSS]], [[Programmation JavaScript|JavaScript]] et [[v:Lua|Lua]], ainsi que certains paramètres, peuvent être modifiés par tous les internautes. Cela peut se faire en se connectant à un compte utilisateur, afin de bénéficier des droits de modification et d’administration qui lui sont accordés, ou en utilisant la configuration attribuée par défaut aux personnes non connectées.
Sur les pages web d'un wiki, chaque modification provoque un nouvel enregistrement complet du [[w:Code_source|code source]] qui la compose. De la sorte, il est toujours possible, à partir d’une page reprenant l’[[w:Historique_(informatique)|historique]] des modifications, de rétablir l'une de ses anciennes versions. Grâce à ce système, on peut ainsi savoir quelle personne, ou quelle [[w:Adresse_IP|adresse IP]] est à l’origine d’un changement, et même voir l’endroit où la modification a été faite, et à quel moment celle-ci a été réalisée.
[[Fichier:Ward_Cunningham_1.jpg|alt=Logo du logiciel MediaWiki, le logiciel Wiki utilisé par les projets Wikimédia et dont le développement est soutenu par la fondation Wikimédia.|gauche|vignette|<small>Figure 12. Ward Cunningham en 2011.</small>|300x300px]]
Le premier logiciel Wiki, qui portait le nom de [[w:fr: WikiWikiWeb|WikiWikiWeb]], a été créé et placé sous licence libre GPL par [[w:fr: Ward Cunningham|Ward Cunningham]] en mars 1995<ref>{{Lien web|auteur=Wiki.c2|titre=Wiki Wiki Web Faq|url=http://web.archive.org/web/20170106225231/http://wiki.c2.com/?WikiWikiWebFaq}}.</ref>. Grâce à la licence, d’autres programmes wiki ont vu le jour en copiant ou s’inspirant du code source de WikiWikiWeb, ou des autres projets wiki qui l'avaient fait auparavant. Cette émulation récursive qui donna naissance à toute une panoplie de projets wiki, est donc à nouveau, une belle illustration des retombées positives, que peut susciter l'application d'une licence libre.
Parmi les différents logiciels Wiki disponibles, [[w:en:UseModWiki|UseModWiki]] fut choisi par la société [[w:fr: Bomis|Bomis]] qui finança la création du premier projet Wikipédia en anglais. Suite à l’éclatement de la [[w:Bulle_Internet|bulle spéculative d’Internet]] en fin des années 2000, ce programme gratuit, simple d’utilisation et peu gourmand en ressources informatiques, convenait de fait parfaitement pour cette entreprise confrontée à de grosses difficultés financières. UseModWiki fut par après remplacé par un autre moteur de Wiki sans nom, mais plus performant et toujours produit sous licence libre<ref>{{Lien web|langue=|auteur=Brion Vibber|titre=MediaWiki's big code & usability code & usability push|url=http://web.archive.org/web/20120517072350/http://leuksman.com/images/8/80/Brion-fosdem2009.pdf|site=Leuksman|date=2009|consulté le=}}.</ref>. Ce dernier fut ensuite amélioré par plusieurs programmeurs, dont Brion Vibber, le premier employé de la [[w:fr: Fondation Wikimédia|Fondation Wikimédia]], avant d’être finalement intitulé [[MediaWiki pour débutants|MediaWiki]].
Avec l’aide de nouveaux employés et des bénévoles actifs sur le site [[mw:Mediawiki|mediawiki.org]], le système de gestion de contenu finit par apparaitre en tête de classement des wikis au niveau de leurs taux d’utilisation<ref>{{Lien web|auteur=Wiki.c2|titre=Top Ten Wiki Engines|url=https://web.archive.org/web/20201127014153/http://wiki.c2.com/?TopTenWikiEngines|consulté le=}}.</ref>. Toujours selon le principe de réciprocité apporté par la licence libre, les efforts produits par la Fondation et son personnel ont permis à des milliers de personnes, projets et sites Web, de se développer en parallèle et sans faire nécessairement partie du mouvement Wikimédia<ref>{{Lien web|langue=|auteur=MediaWiki|titre=Main page|url=https://web.archive.org/web/20201203135522/https://www.mediawiki.org/wiki/MediaWiki|site=|date=|consulté le=}}.</ref>. Entre 2016 et 2020, des centaines de personnes se sont ainsi rassemblés chaque année, <ref>{{Lien web|titre=Category:EMWCon|url=https://web.archive.org/web/20200319063245/https://www.mediawiki.org/wiki/Category:EMWCon|site=|date=|consulté le=|auteur=MediaWiki}}.</ref>, pour discuter du développement et de ses usages du programme<ref>{{Lien web|langue=|auteur=David Strine|titre=MediaWiki is the software that underpins Wikipedia. This conference shows all the other ways it can be used|url=https://web.archive.org/web/20200313181919/https://wikimediafoundation.org/news/2019/05/01/mediawiki-is-the-software-that-underpins-wikipedia-this-conference-shows-all-the-other-ways-it-can-be-used/|site=Wikimedia Foundation News|lieu=|éditeur=|date=1 May 2019|consulté le=}}.</ref>.
Il existe dans la [[w:fr:Liste de logiciels wiki|liste des Wikis]] d’autres logiciels libres intéressants. [[w:Dokuwiki|DokuWiki]], par exemple, est populaire pour sa simplicité d’installation et d’usage. Mais jusqu’à ce jour, seul MediaWiki semble suffisamment stable et puissant pour développer de manière optimale l’ensemble des projets Wikimédia hébergés sur les serveurs de la fondation. Avec parmi ceux-ci, Wikipédia, cette encyclopédie conçue pour être libre et universelle dont nous allons découvrir la naissance dans ce prochain chapitre.
{{AutoCat}}
4vv2o0g8yd4bl1oym8mk2v34izvo4k0
764401
764400
2026-04-22T10:56:19Z
Lionel Scheepmans
20012
764401
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Un [[w:Wiki|wiki]], ou un [[w:Moteur_de_wiki|moteur de wiki]], est un logiciel que l'on installe sur un serveur informatique pour permettre la création d’un site web éditable et configurable à l’aide d’un simple navigateur. Plus précisément, c’est un [[w:Système_de_gestion_de_contenu|système de gestion de contenu]], dans lequel le code [[Le langage HTML|HTML]], [[Le langage CSS|CSS]], [[Programmation JavaScript|JavaScript]] et [[v:Lua|Lua]], ainsi que certains paramètres, peuvent être modifiés par tous les internautes. Cela peut se faire en se connectant à un compte utilisateur, afin de bénéficier des droits de modification et d’administration qui lui sont accordés, ou en utilisant la configuration attribuée par défaut aux personnes non connectées.
Sur les pages web d'un wiki, chaque modification provoque un nouvel enregistrement complet du [[w:Code_source|code source]] qui la compose. De la sorte, il est toujours possible, à partir d’une page reprenant l’[[w:Historique_(informatique)|historique]] des modifications, de rétablir l'une de ses anciennes versions. Grâce à ce système, on peut ainsi savoir quelle personne, ou quelle [[w:Adresse_IP|adresse IP]] est à l’origine d’un changement, et même voir l’endroit où la modification a été faite, et à quel moment celle-ci a été réalisée.
[[Fichier:Ward_Cunningham_1.jpg|alt=Logo du logiciel MediaWiki, le logiciel Wiki utilisé par les projets Wikimédia et dont le développement est soutenu par la fondation Wikimédia.|gauche|vignette|<small>Figure 12. Ward Cunningham en 2011.</small>|300x300px]]
Le premier logiciel Wiki, qui portait le nom de [[w:fr: WikiWikiWeb|WikiWikiWeb]], a été créé et placé sous licence libre GPL par [[w:fr: Ward Cunningham|Ward Cunningham]] en mars 1995<ref>{{Lien web|auteur=Wiki.c2|titre=Wiki Wiki Web Faq|url=http://web.archive.org/web/20170106225231/http://wiki.c2.com/?WikiWikiWebFaq}}.</ref>. Grâce à la licence, d’autres programmes wiki ont vu le jour en copiant ou s’inspirant du code source de WikiWikiWeb, ou des autres projets wiki qui l'avaient fait auparavant. Cette émulation récursive qui donna naissance à toute une panoplie de projets wiki, est donc à nouveau, une belle illustration des retombées positives, que peut susciter l'application d'une licence libre.
Parmi les différents logiciels Wiki disponibles, [[w:en:UseModWiki|UseModWiki]] fut choisi par la société [[w:fr: Bomis|Bomis]] qui finança la création du premier projet Wikipédia en anglais. C'était un choix judicieux, car l’éclatement de la [[w:Bulle_Internet|bulle spéculative d’Internet]] en fin des années 2000, confrontait l'entreprise à de grosses difficultés financières. Un programme gratuit, simple d’utilisation et peu gourmand en ressources informatiques, convenait donc parfaitement dans ce cadre. UseModWiki fut par après remplacé par un autre moteur de Wiki sans nom, mais plus performant et toujours produit sous licence libre<ref>{{Lien web|langue=|auteur=Brion Vibber|titre=MediaWiki's big code & usability code & usability push|url=http://web.archive.org/web/20120517072350/http://leuksman.com/images/8/80/Brion-fosdem2009.pdf|site=Leuksman|date=2009|consulté le=}}.</ref>. Ce dernier fut ensuite amélioré par plusieurs programmeurs, dont Brion Vibber, le premier employé de la [[w:fr: Fondation Wikimédia|Fondation Wikimédia]], avant d’être finalement intitulé [[MediaWiki pour débutants|MediaWiki]].
Avec l’aide de nouveaux employés et des bénévoles actifs sur le site [[mw:Mediawiki|mediawiki.org]], le système de gestion de contenu finit par apparaitre en tête du classement des wikis les plus utilisés<ref>{{Lien web|auteur=Wiki.c2|titre=Top Ten Wiki Engines|url=https://web.archive.org/web/20201127014153/http://wiki.c2.com/?TopTenWikiEngines|consulté le=}}.</ref>. Grâce à la licence libre, des milliers d'autres personnes et projets ont pu en effet développer des sites Web, sans nécessairement faire partie du mouvement Wikimédia<ref>{{Lien web|langue=|auteur=MediaWiki|titre=Main page|url=https://web.archive.org/web/20201203135522/https://www.mediawiki.org/wiki/MediaWiki|site=|date=|consulté le=}}.</ref>. Ce succès a par ailleurs justifié l'organisation de rassemblements annuels entre 2016 et 2020<ref>{{Lien web|titre=Category:EMWCon|url=https://web.archive.org/web/20200319063245/https://www.mediawiki.org/wiki/Category:EMWCon|site=|date=|consulté le=|auteur=MediaWiki}}.</ref>, entre personnes et organisations qui utilisent le programme, pour discuter de son développement et de ses usages<ref>{{Lien web|langue=|auteur=David Strine|titre=MediaWiki is the software that underpins Wikipedia. This conference shows all the other ways it can be used|url=https://web.archive.org/web/20200313181919/https://wikimediafoundation.org/news/2019/05/01/mediawiki-is-the-software-that-underpins-wikipedia-this-conference-shows-all-the-other-ways-it-can-be-used/|site=Wikimedia Foundation News|lieu=|éditeur=|date=1 May 2019|consulté le=}}.</ref>.
Ceci étant dit, il existe dans la [[w:fr:Liste de logiciels wiki|liste des Wikis]] d’autres logiciels libres intéressants, tel que [[w:Dokuwiki|DokuWiki]], qui fut rendu populaire par sa simplicité d’installation et d’usage. Mais jusqu’à ce jour, seul MediaWiki semble suffisamment stable et puissant pour permettre le développement optimal de l’ensemble des projets Wikimédia. Avec parmi ceux-ci, bien sûr, Wikipédia, l'encyclopédie libre et universelle, dont nous allons enfin découvrir la mise en place dans ce prochain chapitre.
{{AutoCat}}
gaf79vi8ew2h5ae73cd40k9hoqz3nng
Le mouvement Wikimédia/L'héritage d'une contre-culture
0
79277
764345
764085
2026-04-22T07:28:30Z
Lionel Scheepmans
20012
764345
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
[[Fichier:Wikimedia-logo black.svg|vignette|150x150px|<small>Figure 21. Logos du mouvement Wikimédia et de sa Fondation.</small>]]
[[Fichier:Peace sign.svg|vignette|150x150px|<small>Figure 22. Logo du mouvement hippie et de la contre-culture.</small>]]
Au terme de cette première partie d’ouvrage, il apparait évident que la révolution numérique, que l’on considère généralement comme une révolution technique, fut aussi, et peut-être avant tout, une révolution sociale et culturelle. Sur base du lancement du projet Wikipédia, nous avons vu comment le mouvement Wikimédia apparait sur le web, comme l'une des manifestations les plus visibles d'un héritage culturel en provenance de la [[w:Contre-culture_des_années_1960|contre-culture des années 1960]]. Soit une philosophie et des valeurs qui s'opposent à une certaine hégémonie culturelle paternaliste, capitaliste et favorable à la marchandisation du monde.
Si le doute persiste encore chez certains à ce propos, ils peuvent alors observer que le renversement du logo du mouvement Wikimédia a une certaine familiarité avec celui du mouvement [[w:fr:Hippie|Hippie]]. Est-ce vraiment un hasard ? Ensuite, Richard Stallman, celui qui a créé le concept d'encyclopédie libre, n'a-t-il pas été perçu comme le gourou de la contre-culture hacker<ref>{{Ouvrage|auteur=|prénom1=Divers|nom1=auteurs|titre=L'Éthique Hacker|passage=11|éditeur=U.C.H Pour la Liberté|date=Version 9.3|pages totales=56|lire en ligne=https://web.archive.org/web/20211031170831/https://repo.zenk-security.com/Others/L%20Ethique%20Hacker.pdf}}.</ref> et le père du système d’exploitation hippie<ref>{{Lien web|langue=|auteur=Gavin Clarke|titre=Stallman's GNU at 30: The hippie OS that foresaw the rise of Apple — and is now trying to take it on|url=https://web.archive.org/web/20230602214539/https://www.theregister.com/2013/10/07/stallman_thiry_years_gnu/|site=Theregister|date=7 Oct 2013|consulté le=}}.</ref> ? Incontestablement et au travers du mouvement des logiciels libres, le mouvement Wikimédia a donc bien hérité des enjeux et des valeurs produits au sein de la contre-culture des années 1960.
D'ailleurs, [[w:fr: André Gorz|André Gorz]], ce philosophe parmi les pères de la [[w:fr: Décroissance|décroissance]]<ref>{{Ouvrage|langue=|prénom1=David|nom1=Murray|prénom2=Cédric|nom2=Biagini|prénom3=Pierre|nom3=Thiesset|prénom4=Cyberlibris|nom4=ScholarVox International|titre=Aux origines de la décroissance: cinquante penseurs|date=2017|isbn=978-2-89719-329-4|isbn2=978-2-89719-330-0|isbn3=978-2-89719-331-7|oclc=1248948596}}.</ref> et théoricien de l’[[w:fr: Écologie politique|écologie politique]]<ref>{{Ouvrage|langue=|prénom1=André|nom1=Gorz|titre=Ecologie et politique: nouv. ed. et remaniee.|éditeur=Éditions du Seuil|date=1978|isbn=978-2-02-004771-5|oclc=796186896}}.</ref>, nous confie d'ailleurs que <ref>{{Lien web|langue=|auteur=André Gorz|titre=Le travail dans la sortie du capitalisme|url=https://web.archive.org/web/20200921155055/http://ecorev.org/spip.php?article641|site=Revue Critique d'Écologie Politique|lieu=|date=7 janvier 2008}}.</ref> :
<blockquote>
La lutte engagée entre les "logiciels propriétaires" et les "logiciels libres" (libre, "free", est aussi l’équivalent anglais de "gratuit") a été le coup d’envoi du conflit central de l’époque. Il s’étend et se prolonge dans la lutte contre la marchandisation de richesses premières – la terre, les semences, le génome, les biens culturels, les savoirs et compétences communs, constitutifs de la culture du quotidien et qui sont les préalables de l’existence d’une société. De la tournure que prendra cette lutte dépend la forme civilisée ou barbare que prendra la sortie du capitalisme.
</blockquote>
[[Fichier:Wikimania_stallman_keynote2.jpg|alt=Photo de Richard Stallman lors du premier rassemblement Wikimania de 2005|vignette|<small>Figure 23. Photo de Richard Stallman lors du premier rassemblement internationnal du mouvement Wikimédia en 2005.</small>|gauche|300x300px]]
Dans le cadre de cette lutte et en possédant un [[w:fr: Nom de domaine|nom de domaine]] parmi le top 100 des plus fréquentés<ref>{{Lien web|auteur=Alexa|titre=Top sites|url=https://www.alexa.com/topsites|consulté le=}}.</ref>, le mouvement Wikimédia est donc une pierre angulaire dans la défense de la liberté, du partage, de l'équité. Parce qu'au-delà du code informatique, s’il y a bien une chose que l'on cherche à marchandiser et à transformer, c’est sans aucun doute le savoir. Un savoir qui se décline en information, lorsqu'il s'agit de récolter tout type de données relatives à l’identité et aux comportements des utilisateurs et des utilisatrices d'Internet. Un « nouvel or noir », diront certains, alors que d’autres préfèrent parler de « capitalisme 3.0<ref>{{Ouvrage|langue=|prénom1=Philippe|nom1=Escande|prénom2=Sandrine|nom2=Cassini|titre=Bienvenue dans le capitalisme 3.0|éditeur=Albin Michel|date=2015|isbn=978-2-226-31914-2|oclc=954080043}}.</ref> » ou encore de « capitalisme de surveillance<ref>{{Ouvrage|langue=|prénom1=Shoshana|nom1=Zuboff|titre=L'âge du capitalisme de surveillance|éditeur=Zulma|date=2020|isbn=978-2-84304-926-2|oclc=1199962619}}.</ref><ref>{{Ouvrage|langue=|prénom1=Christophe|nom1=Masutti|prénom2=Francesca|nom2=Musiani|titre=Affaires privées : aux sources du capitalisme de surveillance|éditeur=Caen : C&F éditions|collection=Société numérique|date=2020|isbn=978-2-37662-004-4|oclc=1159990604|consulté le=}}.</ref> ».
Évidemment, les enjeux de cette lutte sont difficiles à comprendre. La complexité de l’infrastructure informatique, mais également le fait que tout cela s'inscrit dans une révolution que [[w:fr: Rémy Rieffel|Rémy Rieffel]] décrit comme « instable et ambivalente, simultanément porteuse de promesse et lourde de menaces », ne facilitent pas les choses. Cela d'autant plus que tout cela se place « dans un contexte où s’affrontent des valeurs d’émancipation et d’ouverture d’un côté et des stratégies de contrôle et de domination de l’autre<ref>{{Ouvrage|langue=|auteur=|prénom1=Rémy|nom1=Rieffel|titre=Révolution numérique, révolution culturelle ?|passage=20|lieu=|éditeur=Folio|date=2014|pages totales=|isbn=978-2-07-045172-2|oclc=953333541|lire en ligne=|consulté le=}}.</ref> ».
En fait d’ambivalence, certains faits sont significatifs. Il est surprenant, par exemple, d'apprendre que Jimmy Wales est un adepte de l’[[w:fr:Objectivisme (Ayn Rand)|objectivisme]], alors qu'il est fondateur du projet Wikipédia avant de transférer les avoirs de sa société à la fondation Wikimédia. Comment une philosophie politique dans laquelle le capitalisme est perçu comme la forme idéale d’organisation de la société<ref>{{Ouvrage|langue=|prénom1=Ayn|nom1=Rand|prénom2=Nathaniel|nom2=Branden|prénom3=Alan|nom3=Greenspan|prénom4=Robert|nom4=Hessen|titre=Capitalism: the unknown ideal|date=2013|isbn=978-0-451-14795-0|oclc=1052843511|consulté le=}}.</ref> et pour laquelle, l’intention morale de l’existence est la poursuite de l’égoïsme rationnel<ref>{{Ouvrage|langue=|prénom1=Ayn|nom1=Rand|titre=La vertu d'égoïsme|éditeur=Les Belles lettres|date=2011|isbn=978-2-251-39046-8|oclc=937494401|consulté le=}}.</ref>.
Comme preuve d'instabilité apparaissaient ensuite les appels répètés de [[w:fr:Tim Berners-Lee|Tim Berners-Lee]] au sujet de la « [[w:fr:Redécentralisation d'Internet|redécentralisation]]<ref>{{Lien web|langue=|auteur=Liat Clark|titre=Tim Berners-Lee : we need to re-decentralise the web|url=https://web.archive.org/web/20201111164058/https://www.wired.co.uk/article/tim-berners-lee-reclaim-the-web|site=Wired UK|éditeur=|date=6 February 2014|consulté le=}}.</ref> » et la « régulation<ref>{{Lien web|auteur=Elsa Trujillo|titre=Tim Berners-Lee, inventeur du Web, appelle à la régulation de Facebook, Google et Twitter|url=https://web.archive.org/web/20201129111413/https://www.lefigaro.fr/secteur/high-tech/2018/03/12/32001-20180312ARTFIG00179-tim-berners-lee-inventeur-du-web-appelle-a-la-regulation-de-facebook-google-et-twitter.php|site=Le figaro|éditeur=|date=12/03/2018|consulté le=}}.</ref> » de l’espace web dont il fut le concepteur. Cela pendant que des milliards d’[[w:Internet des objets|objets connectés]] à Internet nourrissent un marché qui dépasserait déjà les 2.6 milliards d’euros rien qu’en France et pour l’année 2020<ref>{{Lien web|langue=|auteur=Tristan Gaudiaut|titre=Infographie: L'essor de l'Internet des objets|url=https://web.archive.org/web/20211004110619/https://fr.statista.com/infographie/24353/chiffre-affaires-marche-iot-objets-connectes-france/|site=Statista Infographies|date=30 sept. 2021|consulté le=}}.</ref>.
Au niveau du contrôle et au-delà de ce qui est opéré par les [[w:GAFAM|GAFAM]], c'est bien sûr au niveau des États et des gouvernements que l'attention se porte. Dans le cadre du mouvement Wikimédia, le désir de s’émanciper des contrôles étatiques entraine parfois la censure des projets Wikimédia par des gouvernements. Ce fut ainsi le cas temporairement en Turquie, en Russie, en Iran et même au Royaume-Uni, ou encore en Chine, avec un blocage permanent depuis 2004<ref>{{Lien web|langue=|auteur=Christine Siméone|titre=Censurée en Turquie et en Chine, remise en cause en Russie, ces pays qui en veulent à Wikipédia|url=https://web.archive.org/web/20200225091639/https://www.franceinter.fr/societe/censuree-en-turquie-et-en-chine-remise-en-cause-en-russe-ces-pays-qui-remettent-wikipedia-en-cause|site=France Inter|lieu=|date=2019-12-26|consulté le=}}.</ref>.
Dans d'autres contextes, des procédures juridiques peuvent être utilisées pour intimider les membres du mouvement. Ce fut le cas en France, lorsque le directeur de l’association locale fut menacé de poursuites pénales par la Direction Centrale du Renseignement Intérieures, dans le cadre d’une affaire liée à un article Wikipédia crée au sujet d’une station militaire<ref>{{Lien web|langue=|auteur=Stéphane Moccozet|titre=Une station hertzienne militaire du Puy-de-Dôme au cœur d'un désaccord entre Wikipédia et la DCRI|url=https://web.archive.org/web/20201124101244/https://france3-regions.francetvinfo.fr/auvergne-rhone-alpes/2013/04/06/un-station-hertzienne-militaire-du-puy-de-dome-au-coeur-d-un-desaccord-entre-wipikedia-et-la-dcri-229791.html|site=France 3 Auvergne-Rhône-Alpes|lieu=|date=06/04/2013|consulté le=}}.</ref>. En France, cette intimidation se limita à des menaces, mais en Biélorussie, l’éditeur [[w:Mark_Bernstein|Mark Bernstein]] fut réelement condamné à quinze jours de prison assorti de trois ans d’assignation à résidence, en raison de propos tenus sur la guerre en Ukraine<ref>{{Lien web|titre=Entrepreneur, Activist Mark Bernstein Detained In Minsk - Charter'97 :: News from Belarus - Belarusian News - Republic of Belarus - Minsk|url=https://web.archive.org/web/20220312011414/https://charter97.org/en/news/2022/3/11/458592/|site=Charter97|date=2022-03-11|consulté le=|auteur=Charter97}}.</ref>.
D'un côté, l’espace Web a permis le développement de monopoles lucratif, à l’image des [[w:fr:GAFAM|GAFAM]], [[w:fr:BATX|BATX]], [[w:fr:NATU (Netflix, Airbnb, Tesla et Uber)|NATU]] et autres [[w:fr:Géants du web|géants du web]] accusés d'[[w:fr:Abus de position dominante|abus de position dominante]], alors que de l'autre, certains projets à prétentions commerciales, peuvent étonament donner naissance à des projets de partage autonomes. Comme vu précédement, ce fut le cas du projet commercial Nupedia qui abouti à la création de Wikipédia et de la fondation Wikimédia. Un scénariot très similaire, par ailleurs, à ce qui permis le développement du navigateur [[Firefox]] et la création de la [[w:Mozilla_Foundation|fondation Mozilla]], suite à la faillite de la société commerciale [[w:Netscape_Communications|Netscape Communications]].
Dans un autre contexte, un succès commercial tel que la messagerie instantanée [[w:fr:MSN Messenger|MSN Messenger]], a servi d'inpiration pour d’autres succès commerciaux, à l'images des nombreux réseaux sociaux apparus sur le web. Cela alors qu'au niveau de la sphère du partage autonome, un succès non commercial tel que le projet Wikipédia, a inspiré la création d’autres projets collaboratifs et sans but lucratif, parmi lesquels figure le projet [[w:fr:OpenStreetMap|OpenStreetMap]] dédié à la cartographie du monde sous licence libre.
[[Fichier:Davide_Dormino_-_Anything_to_say.jpg|alt=Davide Dormino prenant place sur sa sculpture debout sur une chaise à côté de trois lanceurs d'alertes|vignette|<small>Figure 24. Sculpture en bronze de Davide Dormino intitulée ''[[w:Anything_to_say?|Anything to say?]]'' à l’honneur des trois lanceurs d’alertes que sont de gauche à droite : Edward Snowden, Julian Assange et Chelsea Manning.</small>|350x350px]]
Tout se passe donc comme si au sein de l’espace numérique se perpétuait une opposition perpétuelle entre d’un côté, une recherche de pouvoir économique et politique centralisé au profit de quelques acteurs privilégiés, et, de l’autre, un désir de partage et d’autonomie défendus par d'autres acteurs de la population humaine.
Dans ce cadre, nous avons ainsi découvert que certains courants sociaux que l’on pourrait croire entièrement disparus continuent d'influencer la manière dont fonctionnent nos sociétés. Car cinquante ans plus tard, et même si les termes et appelations ne sont plus les mêmes, il est évident que la figure emblématique contemporaine du [[w:fr:Lanceur d'alerte|lanceur ou de la lanceuse d’alerte]], est idéologiquement proche des figures contestataires apparues au sein de la contre-culture des années 1960.
Certains Wikimédiens tels que [[w:Aaron Swartz|Aaron Swartz]], [[w:Bassel Khartabil|Bassel Khartabil]], [[w:Pavel_Pernikov|Pavel Pernikov]], [[w:Ihor_Kostenko|Ihor Kostenko]] et [[w:Mark_Bernstein|Mark Bernstein]] ont en effet perdu leur vie ou leur liberté pour défendre les valeurs présentées tout au long de cette première partie d’ouvrage. De manière similaire à [[w:Julian Assange|Julian Assange]], [[w:Edward Snowden|Edward Snowden]] et [[w:Chelsea Manning|Chelsea Manning]], on peut dire d’eux qu’ils « ont perdu leur liberté pour défendre la nôtre »<ref>{{Lien web|titre=Berlin: Des statues à l'effigie des lanceurs d'alerte Snowden, Manning et Assange|url=https://web.archive.org/web/20230326124921/https://www.20minutes.fr/insolite/1601039-20150504-berlin-statues-effigie-lanceurs-alerte-snowden-manning-assange|site=20minutes.fr|date=04/05/2015|consulté le=|auteur=B.D.}}.</ref>.
Même au sein du mouvement Wikimédia et comme cela fut présenté dans l'introduction de cet ouvrage, une alerte peut être lancée sous la forme d'un appel à commentaires pour réagir à une décision prise par la Fondation Wikimédia. En raison d'une organisation et de structures plus proches de ce qui se développe dans le système économique classique, les organisations hors ligne activent au sein du mouvement Wikimédia ne partagent effectivement pas toujours la même vision, ni parfois les mêmes valeurs, que celles développées au sein des communautés de contributeurs bénévoles actifs au sein des projets<ref name=":0">{{Ouvrage|langue=fr|prénom1=Lionel|nom1=Scheepmans|lien auteur1=user:Lionel Scheepmans|titre=Imagine un monde : quand le mouvement Wikimédia nous aide à penser de manière prospective la société globale et numérique de demain|éditeur=UCL - Université Catholique de Louvain|année=2022|date=17/06/2022|lire en ligne=https://dial.uclouvain.be/pr/boreal/object/boreal:264603|consulté le=2024-03-10|nature article=Thèse de doctorat}}</ref>.
Comme dans les autres sites web hébergés par le mouvement, cela n'a pas empêché la communauté de Wikipédia en français de développer de nombreuses [[w:Wikipédia:Règles_et_recommandations|règles et des recommandations]] qui s'apparentent fortement à des lignes éditoriales. Au même titre que le mouvement dans son ensemble a adopté un code de conduite universel dans le but d’établir un « référentiel minimum des comportements acceptables et inacceptables »<ref>{{Lien web|titre=Policy:Universal Code of Conduct/fr|url=https://web.archive.org/web/20251007061014/https://foundation.wikimedia.org/wiki/Policy:Universal_Code_of_Conduct/fr|site=|date=|consulté le=|auteur=Wikimedia Foundation Governance Wiki}}.</ref>. Mais tout cela au sein d'une sorte de « bazar libertaire »<ref>{{Lien web|langue=|auteur=Frédéric Joignot|titre=Wikipédia, bazar libertaire|url=https://web.archive.org/web/20170630065818/http://www.lemonde.fr/technologies/article/2012/01/14/wikipedia-bazar-libertaire_1629135_651865.html|site=Le Monde|lieu=|date=2012|consulté le=}}.</ref>, dont le principe fondateur d'interprétation créative des règles<ref>{{Lien web|langue=|auteur=Wikipédia|titre=Wikipédia: Interprétation créative des règles|url=https://fr.wikipedia.org/wiki/Wikipédia:Interprétation_créative_des_règles|consulté le=}}.</ref> reste affiché jusqu'à ce jour :<blockquote>N’hésitez pas à contribuer, même si vous ne connaissez pas l’ensemble des règles, et si vous en rencontrez une qui, dans votre situation, semble gêner à l’élaboration de l’encyclopédie, ignorez-la ou, mieux, corrigez-la.</blockquote>Une simple phrase, qui a elle seule témoigne de l'héritage de toute une idéologie décrites par Steven Levy dans son ouvrage ''L’Éthique des hackers''<ref>{{Ouvrage|langue=|prénom1=Steven|nom1=Levy|prénom2=Gilles|nom2=Tordjman|titre=L'éthique des hackers|éditeur=Globe|date=2013|isbn=978-2-211-20410-1|oclc=844898302}}.</ref>. Dès sa création en 2001 Wikipédia intégrerait ainsi toute une panoplie d'idées préexistant concernant la conception d'un monde basée sur l'ouverte, la transparence et la liberté.
Ce que démontre cette première partie d'ouvrage, c'est donc que perdure, au sein Wikimédia, comme dans d'autres endroits du monde, une posture réfractaire à la marchandisation du monde combiné à refus de « l’interférence du gouvernement et des grandes sociétés<ref>{{Lien web|auteur=[[w:Timothy C. May|]]|titre=Manifeste Crypto-Anarchiste|url=https://web.archive.org/web/20221208203642/https://www.larevuedesressources.org/manifeste-crypto-anarchiste,2316.html|site=La Revue des Ressources|date=4 mai 2012|consulté le=}}.</ref> ». Cette lutte du partage et de la liberté, contre l'enrichissement et de contrôle n'est pas nouvelle, mais comme cela vient d'être vu, ne cesse d'évoluer dans un monde toujours plus global et numérique.
{{AutoCat}}
86v1p7rjpqbouby6erf4l7491nds5zl
Le mouvement Wikimédia/Le mouvement du logiciel libre
0
79318
764239
757100
2026-04-21T15:19:17Z
Lionel Scheepmans
20012
764239
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’un des premiers épisodes de la préhistoire de Wikipédia et du mouvement Wikimédia débuta en septembre 1983, lorsqu’un programmeur du ''[[w:fr:Massachusetts Institute of Technology|Massachusetts Institute of Technology]]'', appelé [[w:fr:Richard Stallman|Richard Stallman]], déposa un message sur la liste de diffusion net.unix-wizards. C’était un appel d’aide pour la création de [[w:Projet GNU|GNU]], un nouveau [[w:fr:Système d'exploitation|système d’exploitation]] qui devait réunir une suite de programmes que tout le monde pourrait utiliser librement sur son ordinateur personnel<ref>{{Ouvrage|langue=|prénom1=Richard M|nom1=Stallman|prénom2=Sam|nom2=Williams|titre=Richard Stallman et la révolution du logiciel libre - Une biographie autorisée|éditeur=Eyrolles|date=2013|oclc=708380925|lire en ligne=https://framabook.org/docs/stallman/framabook6_stallman_v1_gnu-fdl.pdf|consulté le=}}.</ref>. Dans son message transmis via [[w:Arpanet|ARPANET]], le premier réseau informatique à grande échelle qui précéda Internet, Stallman s’exprimait de la sorte<ref>{{Lien web|langue=|auteur=Richard Stallman|titre=Système d'exploitation GNU – Annonce initiale|url=https://web.archive.org/web/20010106133800/http://www.gnu.org:80/gnu/initial-announcement.fr.html|site=GNU|date=3 décembre 2000|consulté le=}}.</ref> :
<blockquote>
Je considère comme une [[w:Règle d'or|règle d’or]] que si j’apprécie un programme je dois le partager avec d’autres personnes qui l’apprécient. Je ne peux pas en bonne conscience signer un accord de non-divulgation ni un accord de licence de logiciel. Afin de pouvoir continuer à utiliser les ordinateurs sans violer mes principes, j’ai décidé de rassembler une quantité suffisante de logiciels libres, de manière à pouvoir m’en tirer sans aucun logiciel qui ne soit pas libre.
</blockquote>
Le projet de Stallman, qui reçut le soutien nécessaire à son accomplissement, marqua ainsi le début de l’[[w:Histoire_du_logiciel_libre|histoire du logiciel libre]]. Quant à la quantité d’aide fournie, elle permet de croire que Richard Stallman n’était pas seul à voir l’arrivée des [[w:Logiciel propriétaire|logiciels propriétaires]] d’un mauvais œil. Car pour les membres du projet GNU et du mouvement du logiciel libre en général, un bon programme informatique doit respecter ces quatre libertés fondamentales<ref>{{Lien web|langue=|auteur=Karl Pradène|titre=Qu'est-ce que le logiciel libre ?|url=https://web.archive.org/web/20000511101640/http://www.gnu.org/philosophy/free-sw.fr.html|site=GNU|date=6 mai 2000|consulté le=}}.</ref> :
<blockquote>
1. La liberté d’exécuter le programme, pour tous les usages.
2. La liberté d’étudier le fonctionnement du programme, et de l’adapter à vos besoins.
3. La liberté de redistribuer des copies, donc d’aider votre voisin.
4. La liberté d’améliorer le programme, et de publier vos améliorations, pour en faire profiter toute la communauté.
</blockquote>
[[w:Histoire_du_logiciel_libre|Lors de l'apparition du logiciel libre]], le marché de l’informatique était en pleine mutation. L'habituel partage des codes informatiques entre les rares étudiants ou chercheurs qui bénéficiaient d’un accès à un ordinateur, était en effet en train d'être remis en question. Ce changement faisait notamment suite au [[w:Copyright_Act_(1976)|Copyright Act]] de 1976, une nouvelle loi qui rendait possible l'application d'un [[w:Droit_d'auteur|droit d'auteur]] sur le code informatique, et donc qui permettait d'en interdire le partage ou la réutilisation sans autorisation. Des [[w:Clause_de_confidentialité|clauses de confidentialité]] ont ainsi fait leur apparition pendant que les employés des firmes informatiques étaient nouvellement soumis à des contrats de confidentialité. C'était la fin de l’entraide et de la solidarité pratiquées chez les pionniers de l’informatique. À sa place s'installaient la concurrence et la compétitivité, bien connues dans le système capitaliste marchand.
[[Fichier:Commodore64withdisk.jpg|alt=Commodore 64 avec disquette et lecteur|gauche|vignette|<small>Figure 4. Commodore 64 avec disquette et lecteur.</small>|300x300px]]
Cette mutation coïncidait avec l’arrivée des premiers ordinateurs « transportables ». Grâce à l’apparition des premiers [[w:Circuits_intégrés|circuits intégrés]], les premiers exemplaires avaient été créés par l’industrie aérospatiale au début des années 1960. Cependant, il fallut attendre le début des années 1980 pour que le prix d’un ordinateur soit suffisamment bas pour en faire un [[w:Bien_de_grande_consommation|bien de grande consommation]].
C’est ainsi qu’en 1982, le [[w:Commodore 64|Commodore 64]] entrait dans le [[w:Livre_Guinness_des_records|livre Guinness des records]], avec plus de 17 millions d’exemplaires vendus dans le monde<ref>{{Lien web|langue=|auteur=Brandon Griggs|titre=The Commodore 64, that '80 s computer icon, lives again|url=https://web.archive.org/web/20200706161515/http://edition.cnn.com/2011/TECH/gaming.gadgets/05/09/commodore.64.reborn|site=CNN|date=May 9, 2011|consulté le=}}.</ref>. Juste avant cela, en 1981, l’''[[w:fr:IBM PC|IBM Personal Computer]]'' avait déjà fait son apparition, en proposant une [[w:Architecture_(informatique)|architecture]] ouverte qui allait servir de modèle pour toute une gamme d’ordinateurs que l’on désigne toujours aujourd’hui par l’acronyme « PC ».
Pour faire fonctionner ses nouveaux modèles d'ordinateurs, la société IBM avait confié à l’entreprise [[w:Microsoft|Microsoft]], créée en 1975, la mission de les équiper d’un système d’exploitation. Le contrat signé entre les deux firmes fut une véritable aubaine pour le fournisseur des programmes informatiques qui faisaient tourner le nouveau matériel produit par la compagnie IBM. Car sans s'en apercevoir et sans jamais anticiper que son matériel serait cloné à grande échelle, celle-ci avait en effet permis à Microsoft d'établir un monopole dans la vente de logiciels. Cela fut condamné pour [[w:Abus_de_position_dominante|abus de position dominante]]<ref name="Combier_2018_01_24">{{Lien web|langue=fr|auteur=Étienne Combier|titre=Abus de position dominante : les plus grosses amendes de la Commission européenne|url=https://web.archive.org/web/20230511110018/https://www.lesechos.fr/2018/01/abus-de-position-dominante-les-plus-grosses-amendes-de-la-commission-europeenne-982719|périodique=[[w:Les Échos|Les Échos]]|date=2018-01-24|consulté le=}}.</ref> et [[w:Vente_liée_de_logiciels_avec_du_matériel_informatique|vente liée du logiciel avec le matériel informatique]]<ref>{{Lien web|langue=fr|auteur=Marc Rees|titre=Pourquoi la justice européenne a sanctuarisé la vente liée PC et OS|url=https://web.archive.org/web/20230209112015/https://www.nextinpact.com/article/23625/101268-la-justice-europeenne-sanctuarise-vente-liee-pc-et-os|site=nextinpact.com|éditeur=[[w:Next INpact|Next INpact]]|date=2016-07-09|consulté le=}}.</ref>, mais sans pour autant empêcher [[w:Bill_Gates|Bill Gates]], le principal actionnaire de Microsoft, d'être l'homme le plus riche du monde en 1994.
[[Fichier:GNU_and_Tux.svg|alt=Mascotte du projet GNU à gauche et du projet Linux à droite.|vignette|<small>Figure 5. À gauche la mascotte du projet GNU ; à droite celle du projet Linux, appelée Tux.</small>]]
Cependant, pendant que Microsoft renforçait sa position dominante, un nouvel événement majeur allait marquer l’histoire du logiciel libre. Celui-ci fut de nouveau déclenché par un appel à contribution, qui fut cette fois posté le vingt-cinq août 1991 par un jeune étudiant en informatique de 21 ans, appelé [[w:fr:Linus Torvalds|Linus Torvalds]]. Via le système de messagerie [[w:fr:Usenet|Usenet]], son message avait été posté dans une liste de diffusion consacrée au système d’exploitation [[w:fr:Minix|Minix]], une sorte d’[[w:UNIX|UNIX]] simplifié et développé dans un but didactique, par le programmeur [[w:fr:Andrew Tanenbaum|Andrew Tanenbaum]].
Loin d’imaginer que cela ferait de lui une nouvelle célébrité dans le monde du Libre<ref>{{Ouvrage|langue=|prénom1=Linus|nom1=Torvalds|prénom2=David|nom2=Diamond|prénom3=Olivier|nom3=Engler|titre=Il était une fois Linux|éditeur=Osman Eyrolles Multimédia|date=2001|isbn=978-2-7464-0321-5|oclc=48059105}}.</ref>, Torvalds entama son message par le paragraphe suivant<ref>{{Ouvrage|langue=|prénom1=Linus|nom1=Torvalds|prénom2=David|nom2=Diamond|titre=Just for fun : the story of an accidental revolutionary|éditeur=HarperBusiness|date=2002|isbn=978-0-06-662073-2|oclc=1049937833}}.</ref> :
<blockquote>
Je fais un système d’exploitation (gratuit) (juste un hobby, ne sera pas grand et professionnel comme gnu) pour les clones 386 (486) AT. Ce projet est en cours depuis avril et commence à se préparer. J’aimerais avoir un retour sur ce que les gens aiment ou n’aiment pas dans minix, car mon système d’exploitation lui ressemble un peu (même disposition physique du système de fichiers (pour des raisons pratiques) entre autres choses)<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I'd like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons)among other things) ».''</ref>.
</blockquote>
Bien qu’il fût présenté comme un passe-temps, le projet qui répondait au nom de « [[w:fr:Noyau Linux|Linux]] », fut rapidement soutenu par des milliers de programmeurs du monde entier, pour devenir bientôt la pièce manquante du projet GNU. En effet, les contributeurs au projet de Richard Stallman n’avaient pas encore terminé l’écriture du code informatique de son [[w:noyau_de_système_d'exploitation|noyau]] [[w:GNU Hurd|Hurd]], cencé établir la communication entre la [[w:Suite_logicielle|suite logicielle]] produite par GNU et le [[w:Matériel informatique|matériel informatique]]. La fusion des codes produits par les projets GNU et Linux permit dès lors la création d’un système complet, stable et entièrement libre baptisé [[w:GNU/Linux|GNU/Linux]].
[[Fichier:Debian-OpenLogo.svg|gauche|vignette|<small>Figure 6. Logo du système d’exploitation Debian.</small>|264x264px]]
Au départ de ce nouveau système d’exploitation, de nombreuses variantes, que l’on nomme communément « [[w:Distribution_Linux|distributions]] », furent créées par des programmeurs de tous horizons. L’une de celles-ci s’intitule [[w:fr:Debian|Debian]] et tire sa réputation d'être la seule qui est simultanément libre, gratuite et produite par une communauté sans lien direct avec une société commerciale<ref>{{Ouvrage|langue=|auteur=|prénom1=Christophe|nom1=Lazaro|titre=La liberte logicielle|passage=|lieu=|éditeur=Academia Bruylant|collection=Anthropologie Prospective|date=2012|pages totales=56|isbn=978-2-87209-861-3|oclc=1104281978}}.</ref>. Ce qui n'empêche pas pour autant que ce système d’exploitation est à la base de plus de 150 distributions dérivées. Quant à la fiabilité du système Debian, elle se confirme par son usage au sein de nombreuses entreprises et organisations, à l’image de la [[w:Wikimedia_Foundation|Fondation Wikimédia]] qui l’utilise sur [[m:Wikimedia_servers/fr|ses serveurs]] pour héberger les projets qu'elle supporte<ref>{{Lien web|langue=|auteur=Méta-Wiki|titre=Serveurs Wikimedia|url=https://web.archive.org/web/20251113214321/https://meta.wikimedia.org/wiki/Wikimedia_servers/fr|site=|date=|consulté le=}}.</ref>.
En provenance des logiciels libres, l’un des premiers héritages du mouvement Wikimédia fut donc la possibilité d'activer ses serveurs informatiques avec un système d’exploitation en même temps fiable, libre et gratuit. De plus, grâce à l'ouverture de son [[w:Code_source|code source]], celui-ci peut être modifié par la Fondation Wikimédia pour répondre aux besoins spécifiques du mouvement. Après quoi et selon les règles formulées par la [[w:Communauté_du_logiciel_libre|communauté du logiciel libre]], les modifications faites par la fondation deviennent elles-mêmes gratuitement et librement utilisables par d’autres personnes ou organismes.
À ce premier aspect dont aura hérité le mouvement Wikimédia s’ajoute ensuite une innovation méthodologique, toujours en provenance des logiciels libres. Dans son article ''[[w:La_Cathédrale_et_le_Bazar|La Cathédrale et le Bazar]]''<ref>{{Ouvrage|langue=|auteur=|prénom1=Eric Steven|nom1=Raymond|titre=Cathedral and the bazaar|titre original=Cathedral and the bazaar|traduction titre=La cathédrale et le bazar|passage=|lieu=|éditeur=SnowBall Publishing|date=2010|pages totales=|isbn=978-1-60796-228-1|oclc=833142152|lire en ligne=}}.</ref>, [[w:Eric_Raymond|Eric Raymond]] mobilise en effet le terme « [[w:Cathédrale|cathédrale]] » pour désigner le mode de production des logiciels propriétaires, en opposition au mot « [[w:fr:Bazar|bazar]] », qu'il utilise pour qualifier le mode de développement des logiciels libres. D’un côté, il décrit une organisation pyramidale, rigide et statutairement hiérarchisée, comme on peut la voir souvent au sein des entreprises. Tandis que de l’autre, il parle d’une organisation horizontale, flexible et peu hiérarchisée, qu’il a lui-même expérimentée en adoptant le « style de développement de Linus Torvalds – distribuez vite et souvent, déléguez tout ce que vous pouvez déléguer, soyez ouvert jusqu’à la promiscuité »<ref>{{Lien web|langue=|auteur=Eric S. Raymond|traducteur=Sébastien Blondeel|titre=La cathédrale et le bazar|url=https://web.archive.org/web/20200203054716/http://www.linux-france.org/article/these/cathedrale-bazar/cathedrale-bazar-1.html|site=Linux France|lieu=|date=1998|consulté le=}}.</ref>.
À l’instar de la métaphore du quartier numérique présentée dans le précédent chapitre, cette manière de décrire les projets open source nous aide donc ici à mieux comprendre ce qui se passe dans le mouvement Wikimédia. Puisque d'une part, on retrouve effectivement cette « ouverture jusqu’à la promiscuité » dans le libre accès aux projets Wikimédia, alors que d'autre part, tout le monde peut participer aux projets Wikimédia, qu'ils soient en ligne ou hors ligne.
Ces deux observations corroborent donc l’existence d’un deuxième héritage, d’ordre méthodologique cette fois, en provenance du mouvement du logiciel libre. Néanmoins, il nous reste encore à découvrir un phénomène négligé par Eric Raymond durant ses observations, et qui pourtant est d'une importance considérable concernant l'histoire de la révolution numérique. Il s’agit là de l’apparition de la licence libre, de la philosophie qu'elle sous-tend, et de la [[w:Culture_libre|culture libre]] dont elle fut à l’origine.
{{AutoCat}}
8unr15wy5vfvrn4rtuuyd57d5ricjl7
764243
764239
2026-04-21T16:20:44Z
Lionel Scheepmans
20012
764243
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’un des premiers épisodes de la préhistoire de Wikipédia et du mouvement Wikimédia débuta en septembre 1983, lorsqu’un programmeur du ''[[w:fr:Massachusetts Institute of Technology|Massachusetts Institute of Technology]]'', appelé [[w:fr:Richard Stallman|Richard Stallman]], déposa un message sur la liste de diffusion net.unix-wizards. C’était un appel d’aide pour la création de [[w:Projet GNU|GNU]], un nouveau [[w:fr:Système d'exploitation|système d’exploitation]] qui devait réunir une suite de programmes que tout le monde pourrait utiliser librement sur son ordinateur personnel<ref>{{Ouvrage|langue=|prénom1=Richard M|nom1=Stallman|prénom2=Sam|nom2=Williams|titre=Richard Stallman et la révolution du logiciel libre - Une biographie autorisée|éditeur=Eyrolles|date=2013|oclc=708380925|lire en ligne=https://framabook.org/docs/stallman/framabook6_stallman_v1_gnu-fdl.pdf|consulté le=}}.</ref>. Dans son message transmis via [[w:Arpanet|ARPANET]], le premier réseau informatique à grande échelle qui précéda Internet, Stallman s’exprimait de la sorte<ref>{{Lien web|langue=|auteur=Richard Stallman|titre=Système d'exploitation GNU – Annonce initiale|url=https://web.archive.org/web/20010106133800/http://www.gnu.org:80/gnu/initial-announcement.fr.html|site=GNU|date=3 décembre 2000|consulté le=}}.</ref> :
<blockquote>
Je considère comme une [[w:Règle d'or|règle d’or]] que si j’apprécie un programme je dois le partager avec d’autres personnes qui l’apprécient. Je ne peux pas en bonne conscience signer un accord de non-divulgation ni un accord de licence de logiciel. Afin de pouvoir continuer à utiliser les ordinateurs sans violer mes principes, j’ai décidé de rassembler une quantité suffisante de logiciels libres, de manière à pouvoir m’en tirer sans aucun logiciel qui ne soit pas libre.
</blockquote>
Le projet de Stallman, qui reçut le soutien nécessaire à son accomplissement, marqua ainsi le début de l’[[w:Histoire_du_logiciel_libre|histoire du logiciel libre]]. Quant à la quantité d’aide fournie, elle permet de croire que Richard Stallman n’était pas seul à voir l’arrivée des [[w:Logiciel propriétaire|logiciels propriétaires]] d’un mauvais œil. Car pour les membres du projet GNU et du mouvement du logiciel libre en général, un bon programme informatique doit respecter ces quatre libertés fondamentales<ref>{{Lien web|langue=|auteur=Karl Pradène|titre=Qu'est-ce que le logiciel libre ?|url=https://web.archive.org/web/20000511101640/http://www.gnu.org/philosophy/free-sw.fr.html|site=GNU|date=6 mai 2000|consulté le=}}.</ref> :
<blockquote>
1. La liberté d’exécuter le programme, pour tous les usages.
2. La liberté d’étudier le fonctionnement du programme, et de l’adapter à vos besoins.
3. La liberté de redistribuer des copies, donc d’aider votre voisin.
4. La liberté d’améliorer le programme, et de publier vos améliorations, pour en faire profiter toute la communauté.
</blockquote>
[[w:Histoire_du_logiciel_libre|Lors de l'apparition du logiciel libre]], le marché de l’informatique était de fait en pleine mutation. L'habituel partage des codes informatiques entre les rares étudiants ou chercheurs qui bénéficiaient d’un accès à un ordinateur faisait l'objet d'une remise en question. Ce changement faisait notamment suite au [[w:Copyright_Act_(1976)|Copyright Act]] de 1976, une nouvelle loi qui autorisait l'application d'un [[w:Droit_d'auteur|droit d'auteur]] sur le code informatique, et donc qui permettait d'en interdire le partage ou la réutilisation sans autorisation. Des [[w:Clause_de_confidentialité|clauses de confidentialité]] ont ainsi fait leur apparition pendant que les employés des firmes informatiques étaient nouvellement soumis à des contrats de confidentialité. C'était la fin de l’entraide et de la solidarité pratiquées chez les pionniers de l’informatique. À sa place s'installaient la concurrence et la compétitivité, bien connues dans le système capitaliste marchand.
[[Fichier:Commodore64withdisk.jpg|alt=Commodore 64 avec disquette et lecteur|gauche|vignette|<small>Figure 4. Commodore 64 avec disquette et lecteur.</small>|300x300px]]
Cette mutation coïncidait avec l’arrivée des premiers ordinateurs « transportables ». Grâce à l’apparition des premiers [[w:Circuits_intégrés|circuits intégrés]], les premiers exemplaires avaient été créés par l’industrie aérospatiale au début des années 1960. Cependant, il fallut attendre le début des années 1980 pour que le prix d’un ordinateur soit suffisamment bas pour en faire un [[w:Bien_de_grande_consommation|bien de grande consommation]].
C’est ainsi qu’en 1982, le [[w:Commodore 64|Commodore 64]] entrait dans le [[w:Livre_Guinness_des_records|livre Guinness des records]], avec plus de 17 millions d’exemplaires vendus dans le monde<ref>{{Lien web|langue=|auteur=Brandon Griggs|titre=The Commodore 64, that '80 s computer icon, lives again|url=https://web.archive.org/web/20200706161515/http://edition.cnn.com/2011/TECH/gaming.gadgets/05/09/commodore.64.reborn|site=CNN|date=May 9, 2011|consulté le=}}.</ref>. Juste avant cela, en 1981, l’''[[w:fr:IBM PC|IBM Personal Computer]]'' avait déjà fait son apparition, en proposant une [[w:Architecture_(informatique)|architecture]] ouverte qui allait servir de modèle pour toute une gamme d’ordinateurs que l’on désigne toujours aujourd’hui par l’acronyme « PC ».
Pour faire fonctionner ses nouveaux modèles d'ordinateurs, la société IBM avait confié à l’entreprise [[w:Microsoft|Microsoft]], créée en 1975, la mission de les équiper d’un système d’exploitation. Le contrat signé entre les deux firmes fut une véritable aubaine pour le fournisseur des programmes informatiques, qui faisaient tourner le nouveau matériel produit par la compagnie IBM. Car sans s'en apercevoir et sans jamais anticiper que son matériel serait cloné à grande échelle, celle-ci avait en effet permis à Microsoft d'établir un monopole dans la vente de logiciels. Cela fut condamné pour [[w:Abus_de_position_dominante|abus de position dominante]]<ref name="Combier_2018_01_24">{{Lien web|langue=fr|auteur=Étienne Combier|titre=Abus de position dominante : les plus grosses amendes de la Commission européenne|url=https://web.archive.org/web/20230511110018/https://www.lesechos.fr/2018/01/abus-de-position-dominante-les-plus-grosses-amendes-de-la-commission-europeenne-982719|périodique=[[w:Les Échos|Les Échos]]|date=2018-01-24|consulté le=}}.</ref> et [[w:Vente_liée_de_logiciels_avec_du_matériel_informatique|vente liée du logiciel avec le matériel informatique]]<ref>{{Lien web|langue=fr|auteur=Marc Rees|titre=Pourquoi la justice européenne a sanctuarisé la vente liée PC et OS|url=https://web.archive.org/web/20230209112015/https://www.nextinpact.com/article/23625/101268-la-justice-europeenne-sanctuarise-vente-liee-pc-et-os|site=nextinpact.com|éditeur=[[w:Next INpact|Next INpact]]|date=2016-07-09|consulté le=}}.</ref>, mais sans pour autant empêcher [[w:Bill_Gates|Bill Gates]], le principal actionnaire de Microsoft, d'être l'homme le plus riche du monde en 1994.
[[Fichier:GNU_and_Tux.svg|alt=Mascotte du projet GNU à gauche et du projet Linux à droite.|vignette|<small>Figure 5. À gauche la mascotte du projet GNU ; à droite celle du projet Linux, appelée Tux.</small>]]
Cependant, pendant que Microsoft renforçait sa position dominante, un nouvel événement majeur allait marquer l’histoire du logiciel libre. Celui-ci fut de nouveau déclenché par un appel à contribution, qui fut cette fois posté le vingt-cinq août 1991 par un jeune étudiant en informatique de 21 ans, appelé [[w:fr:Linus Torvalds|Linus Torvalds]]. Via le système de messagerie [[w:fr:Usenet|Usenet]], son message avait été posté dans une liste de diffusion consacrée au système d’exploitation [[w:fr:Minix|Minix]], une sorte d’[[w:UNIX|UNIX]] simplifié et développé dans un but didactique, par le programmeur [[w:fr:Andrew Tanenbaum|Andrew Tanenbaum]].
Loin d’imaginer que cela ferait de lui une nouvelle célébrité dans le monde du Libre<ref>{{Ouvrage|langue=|prénom1=Linus|nom1=Torvalds|prénom2=David|nom2=Diamond|prénom3=Olivier|nom3=Engler|titre=Il était une fois Linux|éditeur=Osman Eyrolles Multimédia|date=2001|isbn=978-2-7464-0321-5|oclc=48059105}}.</ref>, Torvalds entama son message par le paragraphe suivant<ref>{{Ouvrage|langue=|prénom1=Linus|nom1=Torvalds|prénom2=David|nom2=Diamond|titre=Just for fun : the story of an accidental revolutionary|éditeur=HarperBusiness|date=2002|isbn=978-0-06-662073-2|oclc=1049937833}}.</ref> :
<blockquote>
Je fais un système d’exploitation (gratuit) (juste un hobby, ne sera pas grand et professionnel comme gnu) pour les clones 386 (486) AT. Ce projet est en cours depuis avril et commence à se préparer. J’aimerais avoir un retour sur ce que les gens aiment ou n’aiment pas dans minix, car mon système d’exploitation lui ressemble un peu (même disposition physique du système de fichiers (pour des raisons pratiques) entre autres choses)<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones. This has been brewing since april, and is starting to get ready. I'd like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the file-system (due to practical reasons)among other things) ».''</ref>.
</blockquote>
Bien qu’il fût présenté comme un passe-temps, le projet qui répondait au nom de « [[w:fr:Noyau Linux|Linux]] », fut rapidement soutenu par des milliers de programmeurs du monde entier, pour devenir bientôt la pièce manquante du projet GNU. En effet, les contributeurs au projet de Stallman n’avaient pas encore terminé l’écriture du code informatique du [[w:noyau_de_système_d'exploitation|noyau]] [[w:GNU Hurd|Hurd]], alors qu'il était censé établir la communication entre la [[w:Suite_logicielle|suite logicielle]] produite par GNU et le [[w:Matériel informatique|matériel informatique]]. C'est donc la fusion des codes produits par les projets GNU et Linux qui permit la création du premier système complet, stable et entièrement libre baptisé [[w:GNU/Linux|GNU/Linux]].
[[Fichier:Debian-OpenLogo.svg|gauche|vignette|<small>Figure 6. Logo du système d’exploitation Debian.</small>|264x264px]]
Au départ de ce nouveau système d’exploitation, de nombreuses variantes, que l’on nomme communément « [[w:Distribution_Linux|distributions]] », furent créées par des programmeurs de tous horizons. L’une de celles-ci s’intitule [[w:fr:Debian|Debian]] et tire sa réputation d'être la seule qui est simultanément libre, gratuite et produite par une communauté sans lien direct avec une société commerciale<ref>{{Ouvrage|langue=|auteur=|prénom1=Christophe|nom1=Lazaro|titre=La liberte logicielle|passage=|lieu=|éditeur=Academia Bruylant|collection=Anthropologie Prospective|date=2012|pages totales=56|isbn=978-2-87209-861-3|oclc=1104281978}}.</ref>. Ce qui n'a pas empêché pour autant que le code de ce système informatique soit récupéré par plus de 150 distributions dérivées. Quant à la fiabilité du système Debian, elle se confirme par son usage au sein de nombreuses entreprises et organisations, à l’image de la [[w:Wikimedia_Foundation|Fondation Wikimédia]] qui l’utilise sur [[m:Wikimedia_servers/fr|ses serveurs]] pour héberger les projets qu'elle supporte<ref>{{Lien web|langue=|auteur=Méta-Wiki|titre=Serveurs Wikimedia|url=https://web.archive.org/web/20251113214321/https://meta.wikimedia.org/wiki/Wikimedia_servers/fr|site=|date=|consulté le=}}.</ref>.
En provenance des logiciels libres, l’un des premiers héritages du mouvement Wikimédia fut donc la possibilité d'activer ses serveurs informatiques avec un système d’exploitation fiable, libre et gratuit. Ensuite, et cela grâce à l'ouverture du [[w:Code_source|code source]], de permettre à la Fondation Wikimédia de modifier celui-ci pour répondre aux besoins spécifiques du mouvement. À la suite de quoi, et selon les règles formulées par la [[w:Communauté_du_logiciel_libre|communauté du logiciel libre]], les modifications faites par la Fondation deviennent à leur tour, gratuitement et librement, utilisables par d’autres personnes ou organismes.
À ce premier héritage reçu par le mouvement Wikimédia s’ajoute ensuite une innovation méthodologique, toujours en provenance des logiciels libres. Dans son article ''[[w:La_Cathédrale_et_le_Bazar|La Cathédrale et le Bazar]]''<ref>{{Ouvrage|langue=|auteur=|prénom1=Eric Steven|nom1=Raymond|titre=Cathedral and the bazaar|titre original=Cathedral and the bazaar|traduction titre=La cathédrale et le bazar|passage=|lieu=|éditeur=SnowBall Publishing|date=2010|pages totales=|isbn=978-1-60796-228-1|oclc=833142152|lire en ligne=}}.</ref>, [[w:Eric_Raymond|Eric Raymond]] mobilise en effet le terme « [[w:Cathédrale|cathédrale]] » pour désigner le mode de production des logiciels propriétaires, en opposition au mot « [[w:fr:Bazar|bazar]] », qu'il utilise pour qualifier le mode de développement des logiciels libres. D’un côté, il décrit une organisation pyramidale, rigide et statutairement hiérarchisée, comme on peut la voir souvent au sein des entreprises. Tandis que de l’autre, il parle d’une organisation horizontale, flexible et peu hiérarchisée, qu’il a lui-même expérimentée en adoptant le « style de développement de Linus Torvalds – distribuez vite et souvent, déléguez tout ce que vous pouvez déléguer, soyez ouvert jusqu’à la promiscuité »<ref>{{Lien web|langue=|auteur=Eric S. Raymond|traducteur=Sébastien Blondeel|titre=La cathédrale et le bazar|url=https://web.archive.org/web/20200203054716/http://www.linux-france.org/article/these/cathedrale-bazar/cathedrale-bazar-1.html|site=Linux France|lieu=|date=1998|consulté le=}}.</ref>.
À l’instar de la métaphore du quartier numérique présentée dans le précédent chapitre, cette manière de décrire les projets open source nous aide donc ici à mieux comprendre ce qui se passe dans le mouvement Wikimédia. D'un côté, on retrouve effectivement cette « ouverture jusqu’à la promiscuité », au niveau du libre accès accordé aux projets Wikimédia, alors que de l'autre, tout le monde peut participer aux projets Wikimédia, qu'ils soient en ligne ou hors ligne.
Ces deux observations corroborent donc l’existence d’un deuxième héritage, d’ordre méthodologique cette fois, en provenance du mouvement du logiciel libre. Néanmoins, il nous reste encore à découvrir un phénomène négligé par Eric Raymond durant ses observations, et qui pourtant est d'une importance considérable concernant l'histoire de la révolution numérique. Il s’agit là de l’apparition de la licence libre, de la philosophie qu'elle sous-tend, et de la [[w:Culture_libre|culture libre]] dont elle fut à l’origine.
{{AutoCat}}
30nakww9b77zp5kzw92ovx6u0m0h1nr
Le mouvement Wikimédia/Les licences et la culture libres
0
79320
764261
760584
2026-04-21T18:41:21Z
Lionel Scheepmans
20012
764261
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Dans une biographie autorisée<ref name="Williams">{{Ouvrage|langue=|prénom1=Sam|nom1=Williams|prénom2=Richard M|nom2=Stallman|prénom3=Christophe|nom3=Masutti|titre=Richard Stallman et la révolution du logiciel libre : une biographie autorisée|passage=180|lieu=|éditeur=Livio éditions|date=2020|pages totales=|isbn=978-2-35455-034-9|oclc=1163855816}}.</ref>, Christophe Masutti explique à quel point la création de la [[w:Licence_publique_générale_GNU|Licence publique générale GNU]], en tant que première [[w:Licence_libre|licence libre]] créée par Richard Stallman, représente un épisode majeur de la révolution numérique. Selon lui :
<blockquote>
La GPL apparaît comme l’un des meilleurs ''hacks'' de Stallman. Elle a créé un système de propriété collective à l’intérieur même des habituels murs du copyright. Surtout, elle a mis en lumière la possibilité de traiter de façon similaire « code » juridique et code logiciel.
</blockquote>[[Fichier:GreenCopyleft.svg|alt=Classification des licences d'exploitation des œuvres de l'esprit.|vignette|<small>Figure 7. Symbole du copyleft</small> que l’on traduit par « gauche d’auteur » en français<small>.</small>|150x150px]]Le concept de distribution associé à ce nouveau type de licence fut baptisé « ''[[w:fr : Copyleft|copyleft]]'' », par inspiration d’un jeu de mots que Richard Stallman avait trouvé dans un courrier transmis par son collègue [[w:fr : Don Hopkins|Don Hopkins]]<ref>{{Lien web|langue=|auteur=Richard Stallman|titre=Le projet GNU|url=https://web.archive.org/web/20001207151100/http://www.gnu.org:80/gnu/thegnuproject.fr.html|site=GNU|date=3 décembre 2000|consulté le=}}.</ref>. Le principe novateur de ce concept est d'obliger toute production de code dérivé à se soumettre à la même licence libre que le code d’origine<ref>{{Ouvrage|langue=|auteur=|prénom1=Andrew M|nom1=St. Laurent|titre=Understanding open source & free software licensing [guide to navigating licensing issues in existing & new software|passage=157|lieu=|éditeur=Sebastopol, Ca : O'Reilly Media Inc.|date=2004|pages totales=|isbn=978-0-596-00581-8|oclc=314704943}}.</ref>. C’est d’ailleurs la raison pour laquelle beaucoup de gens parlent de licence « virale » ou « récursive » en faisant référence à celle-ci. Quant à l'importance de cette clause, elle repose sur le fait d'interdire toute privatisation d'un code informatique produit sous licence libre. Sans celle-ci, un tel code risque en effet d'être récupéré, puis modifié, avant d’être placé sous un habituel copyright de type « tous droits réservés », dans le but de commercialiser son usage.
En 2001 et dans la mouvance provoquée par l'arrivée des premières licences libres, une organisation internationale sans but lucratif, intitulée [[w:Creative_Commons|Creative Commons]], a entamé la promotion du « partage et la réutilisation de la créativité et des connaissances grâce à la fourniture d’outils juridiques gratuits ». Pour ce faire, elle met régulièrement à jour une panoplie de licences inspirées par la GNU, mais spécialement adaptées aux œuvres de l'esprit<ref>{{Lien web|auteur=Creative Commons|titre=Foire aux questions|url=https://web.archive.org/web/20251210070542/https://creativecommons.org/faq/fr/}}.</ref>, telles que les productions littéraires, musicales, photographiques et vidéo, ainsi que les bases de données.
[[Fichier:Creative_commons_license_spectrum_fr.svg|alt=Classement des différentes licences, de la plus ouverte à la moins ouverte.|gauche|vignette|<small>Figure 8. Classement des différentes licences, de la plus ouverte à la moins ouverte.</small>]]
Contrairement aux licences libres fournies par la ''[[w:Free_Software_Foundation|Free Software Foundation]],'' conçues pour protéger du code informatique, les licences produites par Creative Commons offrent la possibilité de sélectionner différentes clauses pour protéger une [[w:Œuvre_libre|œuvre libre]]. Avec le label CC, pour Creative Commons, on peut ainsi appliquer, ou ne pas appliquer, la clause « BY », qui oblige à créditer l'auteur, et la clause « SA », pour ''Share Alike'', qui ordonne le partage à l’identique comme décrit précédemment. Après quoi il est encore possible d'ajouter la clause « NC », qui impose un usage non commercial, et finalement, la clause « ND », pour ''Non Derivative'', qui exige que l’œuvre soit utilisée ou reproduite dans son intégralité et sans modification.
Le mouvement Wikimédia a choisi la licence CC.BY-SA pour protéger les contenus publiés dans tous ses projets. Cela à l'exception de la banque de données [[w:fr:Wikidata|Wikidata]], qui au même titre que les descriptions apportées aux fichiers téléchargés dans la médiathèque [[c:Commons:Licensing/fr#Text_(structured_data,_descriptions,_etc.)|Wikimedia Commons]]<ref>{{Lien web|titre=À propos des licences - Wikimedia Commons|url=https://web.archive.org/web/20250906064542/https://commons.wikimedia.org/wiki/Commons:Licensing/fr#Text_(structured_data,_descriptions,_etc.)|auteur=Wikimedia Commons}}</ref>, publie ses [[w:Informations_structurées|informations structurées]] sous [[w:Licence_CC0|licence CC0]]. Cette dernière licence proposée par ''creative commons'' est ce qui se rapproche le plus du [[w:domaine_public_(propriété_intellectuelle)|domaine public]], avec pour avantage de ne pas devoir mentionner les auteurs dans le traitement et la réutilisation du contenu de la base de données.
Cependant, il en résulte que les informations en question peuvent être réutilisées par des tiers qui ne sont plus obligés de citer leurs sources, comme le font les agents conversationnels des [[w:Intelligence_artificielle_générative|intelligences artificielles génératives]], appelés couramment [[w:Chatbot|chatbots]]. Contrairement à la licence CC.BY-SA, la licence CC0 est donc moins apte à pérenniser les projets Wikimédia, puisqu'elle permet d'invisibiliser ces derniers au risque de réduire les chances d'arrivée de nouveaux contributeurs et contributrices. De plus, sans la clause SA qui assure l'application du copyleft, toutes les informations récupérées au sein de Wikidata et de Wikimedia Commons sont aussi susceptibles de quitter le monde du libre, une fois traitées par des entreprises commerciales.
Quoi qu’il en soit, les licences Creative Commons, inspirées par la licence libre de Richard Stallman, apparaissent finalement comme un troisième héritage en provenance du mouvement du logiciel libre et de la [[w:Culture_libre|culture libre]] qui en est issue. Grâce à la licence CC.BY-SA, les éditeurs des projets Wikimédia bénéficient effectivement d'une certaine reconnaissance, tout en étant assurés qu'aucun copyright sur leurs travaux ne puisse profiter exclusivement à une personne ou une compagnie. Cela pendant que la licence libre appliquée au système d'exploitation installé sur les serveurs Wikimédia garantit, pour sa part, un certain respect des contributeurs, puisqu'elle permet de vérifier si le code informatique ne compromet pas leurs vies privées.
Avec tous les autres apports en provenance du logiciel libre, ce sont là deux choses importantes qui ont permis l'apparition du mouvement Wikimédia. Toutefois, cela ne pouvait pas suffire à la création du projet Wikipédia qui en fut le point de départ. Car pour que cette encyclopédie collaborative puisse voir le jour, l'arrivée d'Internet et son espace web, en tant qu'espace numérique mondial et libre d’accès, était encore nécessaire.{{AutoCat}}
cdo7q6j8k0a2n18k0i0kcj3t4zzm1r4
764262
764261
2026-04-21T18:51:28Z
Lionel Scheepmans
20012
764262
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
Dans une biographie autorisée<ref name="Williams">{{Ouvrage|langue=|prénom1=Sam|nom1=Williams|prénom2=Richard M|nom2=Stallman|prénom3=Christophe|nom3=Masutti|titre=Richard Stallman et la révolution du logiciel libre : une biographie autorisée|passage=180|lieu=|éditeur=Livio éditions|date=2020|pages totales=|isbn=978-2-35455-034-9|oclc=1163855816}}.</ref>, Christophe Masutti explique à quel point la création de la [[w:Licence_publique_générale_GNU|Licence publique générale GNU]], en tant que première [[w:Licence_libre|licence libre]] créée par Richard Stallman, représente un épisode majeur de la révolution numérique. Selon lui :
<blockquote>
La GPL apparaît comme l’un des meilleurs ''hacks'' de Stallman. Elle a créé un système de propriété collective à l’intérieur même des habituels murs du copyright. Surtout, elle a mis en lumière la possibilité de traiter de façon similaire « code » juridique et code logiciel.
</blockquote>[[Fichier:GreenCopyleft.svg|alt=Classification des licences d'exploitation des œuvres de l'esprit.|vignette|<small>Figure 7. Symbole du copyleft</small> que l’on traduit par « gauche d’auteur » en français<small>.</small>|150x150px]]Le concept de distribution associé à ce nouveau type de licence fut baptisé « ''[[w:fr : Copyleft|copyleft]]'' », par inspiration d’un jeu de mots que Richard Stallman avait trouvé dans un courrier transmis par son collègue [[w:fr : Don Hopkins|Don Hopkins]]<ref>{{Lien web|langue=|auteur=Richard Stallman|titre=Le projet GNU|url=https://web.archive.org/web/20001207151100/http://www.gnu.org:80/gnu/thegnuproject.fr.html|site=GNU|date=3 décembre 2000|consulté le=}}.</ref>. Le principe novateur de ce concept est d'obliger toute production de code dérivé à se soumettre à la même licence libre que le code d’origine<ref>{{Ouvrage|langue=|auteur=|prénom1=Andrew M|nom1=St. Laurent|titre=Understanding open source & free software licensing [guide to navigating licensing issues in existing & new software|passage=157|lieu=|éditeur=Sebastopol, Ca : O'Reilly Media Inc.|date=2004|pages totales=|isbn=978-0-596-00581-8|oclc=314704943}}.</ref>. C’est d’ailleurs la raison pour laquelle beaucoup de gens parlent de licence « virale » ou « récursive » en faisant référence à celle-ci. Quant à l'importance de cette clause, elle repose sur le fait d'interdire toute privatisation d'un code informatique produit sous licence libre. Sans celle-ci, un tel code risque en effet d'être récupéré, puis modifié, avant d’être placé sous un habituel copyright de type « tous droits réservés », dans le but de commercialiser son usage.
En 2001 et dans la mouvance provoquée par l'arrivée des premières licences libres, une organisation internationale sans but lucratif, intitulée [[w:Creative_Commons|Creative Commons]], a entamé la promotion du « partage et la réutilisation de la créativité et des connaissances grâce à la fourniture d’outils juridiques gratuits ». Pour ce faire, elle met régulièrement à jour une panoplie de licences inspirées par la GNU, mais spécialement adaptées aux œuvres de l'esprit<ref>{{Lien web|auteur=Creative Commons|titre=Foire aux questions|url=https://web.archive.org/web/20251210070542/https://creativecommons.org/faq/fr/}}.</ref>, telles que les productions littéraires, musicales, photographiques et vidéo, ainsi que les bases de données.
[[Fichier:Creative_commons_license_spectrum_fr.svg|alt=Classement des différentes licences, de la plus ouverte à la moins ouverte.|gauche|vignette|<small>Figure 8. Classement des différentes licences, de la plus ouverte à la moins ouverte.</small>]]
Contrairement aux licences libres fournies par la ''[[w:Free_Software_Foundation|Free Software Foundation]],'' conçues pour protéger du code informatique, les licences produites par Creative Commons offrent la possibilité de sélectionner différentes clauses pour protéger une [[w:Œuvre_libre|œuvre libre]]. Avec le label CC, pour Creative Commons, on peut ainsi appliquer, ou ne pas appliquer, la clause « BY », qui oblige à créditer l'auteur, et la clause « SA », pour ''Share Alike'', qui ordonne le partage à l’identique comme décrit précédemment. Après quoi il est encore possible d'ajouter la clause « NC », qui impose un usage non commercial, et finalement, la clause « ND », pour ''Non Derivative'', qui exige que l’œuvre soit utilisée ou reproduite dans son intégralité et sans modification.
Le mouvement Wikimédia a choisi la licence CC.BY-SA pour protéger les contenus publiés dans tous ses projets. Cela à l'exception de la banque de données [[w:fr:Wikidata|Wikidata]], qui au même titre que les descriptions apportées aux fichiers téléchargés dans la médiathèque [[c:Commons:Licensing/fr#Text_(structured_data,_descriptions,_etc.)|Wikimedia Commons]]<ref>{{Lien web|titre=À propos des licences - Wikimedia Commons|url=https://web.archive.org/web/20250906064542/https://commons.wikimedia.org/wiki/Commons:Licensing/fr#Text_(structured_data,_descriptions,_etc.)|auteur=Wikimedia Commons}}</ref>, publie ses [[w:Informations_structurées|informations structurées]] sous [[w:Licence_CC0|licence CC0]]. Cette dernière licence proposée par ''creative commons'' est ce qui se rapproche le plus du [[w:domaine_public_(propriété_intellectuelle)|domaine public]], avec pour avantage de ne pas devoir mentionner les auteurs dans le traitement et la réutilisation du contenu de la base de données.
Cependant, il en résulte que les informations en question peuvent être réutilisées par des tiers qui ne sont plus obligés de citer leurs sources, comme le font les agents conversationnels des [[w:Intelligence_artificielle_générative|intelligences artificielles génératives]], appelés couramment [[w:Chatbot|chatbots]]. Contrairement à la licence CC.BY-SA, la licence CC0 est donc moins apte à pérenniser les projets Wikimédia, puisqu'elle permet d'invisibiliser ces derniers au risque de réduire les chances d'arrivée de nouveaux contributeurs et contributrices. De plus, sans la clause SA qui assure l'application du copyleft, toutes les informations récupérées au sein de Wikidata et de Wikimedia Commons sont aussi susceptibles de quitter le monde du libre, une fois traitées par des entreprises commerciales.
Quoi qu’il en soit, les licences Creative Commons, inspirées par la licence libre de Richard Stallman, apparaissent finalement comme un troisième héritage en provenance du mouvement du logiciel libre et de la [[w:Culture_libre|culture libre]] qui en est issue. Grâce à la licence CC.BY-SA, les éditeurs des projets Wikimédia bénéficient effectivement d'une certaine reconnaissance, tout en étant assurés qu'aucun copyright sur leurs travaux ne puisse profiter exclusivement à une personne ou une compagnie. Cela pendant que la licence libre appliquée au système d'exploitation installé sur les serveurs Wikimédia garantit, pour sa part, un certain respect des contributeurs, puisqu'elle permet de vérifier si le code informatique ne compromet pas leurs vies privées.
Avec tous les autres apports en provenance du logiciel libre, ce sont là deux choses importantes qui ont permis l'apparition du mouvement Wikimédia. Toutefois, cela ne pouvait pas suffire à la création du projet Wikipédia qui en fut le point de départ. Car sans l'espace numérique, mondial et libre d’accès, créé par Internet et l'espace web, aucune encyclopédie collaborative de cette envergure n'aurait pu voir le jour.{{AutoCat}}
lh16i73qlz4edekf1www72m8hxlvmho
Le mouvement Wikimédia/Le réseau Internet
0
79340
764263
757340
2026-04-21T19:31:19Z
Lionel Scheepmans
20012
764263
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Celui-ci fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. Le projet fut ensuite présenté lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' par son auteur [[w:fr:Michel Elie|Michel Elie]], apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. En témoignant d’une familiarité entre la création d’Internet et le fonctionnement de Wikipédia, cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci :
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Il est vrai qu’à l’époque de la création d’Internet, l’atmosphère qui régnait dans les milieux universitaires était encore fortement imprégnée des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], qui était apparue aux États-Unis au sein des [[w:Baby_boomer|''baby boomers'']] et popularisée au cours de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Dans un ouvrage publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>, [[w:fr : Theodore Roszak|Théodore Roszak]] expliquait à ce sujet :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Suite à cette lecture, il peut sembler paradoxal qu’une contre-culture qui voit dans la technique une chose « inférieure et marginale » et qui porte sur la science un regard « banal », puisse avoir eu un quelconque lien avec la création d’Internet et l’apparition des logiciels et licences libres. Toutefois, la réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Comme expliqué dans cet ouvrage, le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre témoignage du passé, il y a aussi les propos tenus par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça deux phrases qui sont restées dans les annales, tout en illustrant la proximité entre les idées de la contre-culture en question et des jeunes informaticiens de l’époque<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref>. La première était : « Nous récusons rois, présidents et votes » et la seconde : « Nous croyons au consensus et aux programmes qui tournent »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject kings, presidents and voting. We believe in rough consensus and running code »''</ref>. Deux phrases qui semblent indiquer que le mépris de la contre-culture des années 60, envers la technique et la science, se transforma en refus d’autorité et en recherche de consensus dans le milieu informatique universitaire.
Ces nouvelles nous aident à comprendre que la création d'un réseau Internet fut le théâtre d'une bataille idéologique, opposant des acteurs sans but lucratif, en recherche de liberté et d’indépendance, à d’autres acteurs commerciaux, en quête de profit financiers. À ce propos, il est intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car suite à un appel à des fonds privés pour financer d'importants changements d'infrastructure du réseau en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est devenu un réseau dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce nouveau paradigme, les acteurs libres et à but non lucratif persistent au bas de l'échelle, à l'exception du [[w:Nom_de_domaine|nom de domaine]] Wikipédia, qui reste le seul à être géré par une fondation parmi les 100 autres [[w:_Liste_des_sites_web_les_plus_visités|les plus visités sur le web]]<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. En ce sens, le mouvement Wikimédia, supporté par cette fondation, apparait comme l'expression la plus visible sur le Web de l’état d’esprit des pionniers d’Internet.
Apparait donc ici l'expression d'un nouvel héritage d'importance, mais qui ne suffi à compléter la liste des conditions nécessaires à la création d’une encyclopédie mondiale, libre et collaborative. Car si l’on revient à la métaphore d’une ville numérique, Internet ne représente pas un espace, mais seulement les routes qui permettent de relier des ordinateurs entre eux. Pareillement au monde géographique, le réseau routier a donc été créé avant les bâtiments, tandis que dans la ville numérique, c’est le World Wide Web, en tant que nouvel outil informatique, qui a permis la construction de l’espace urbain et de ses quartiers constitués de sites web.{{AutoCat}}
n1v9v6oymtyqivs8m999d1mbcntlr27
764268
764263
2026-04-21T20:44:23Z
Lionel Scheepmans
20012
764268
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Celui-ci fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. Le projet fut ensuite présenté lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' par son auteur [[w:fr:Michel Elie|Michel Elie]], apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. En témoignant d’une familiarité entre la création d’Internet et le fonctionnement de Wikipédia, cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci :
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Revenir sur ce sujet est l'occasion de citer un ouvrage intéressant, publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut être paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre réponse au paradoxe, il y a ensuite les propos tenus en 1992 par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales : « Nous récusons : rois, présidents et votes. Nous croyons : au consensus et aux programmes qui tournent. »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases qui permettent ainsi de croire que le mépris de la contre-culture des années 1960 envers la technique et la science a pu se transformer en un refus d’autorité et une recherche de consensus, dans le milieu informatique universitaire de 1990.
Ce qui ne fait aucun doute en revanche, c'est que le développement du réseau Internet fut le théâtre de conflits idéologiques importants. À ce propos, il est d'ailleurs intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car, à la suite d'un appel à des fonds privés pour financer d'importants changements d'infrastructure en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est ainsi devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dont l'usage est dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce contexte et parmi les 100 sites web [[w:_Liste_des_sites_web_les_plus_visités|les sites web les plus visités]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia, reste d'une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. On peut donc dire à ce jour que le mouvement Wikimédia, au travers de son encyclopédie et de sa fondation qui la supporte, représente l'expression la plus visible sur le Web de la philosophie des pionniers d’Internet.
Apparait donc ici l'expression d'un nouvel héritage d'importance, mais qui ne suffi à compléter la liste des conditions nécessaires à la création d’une encyclopédie mondiale, libre et collaborative. Car si l’on revient à la métaphore d’une ville numérique, Internet ne représente pas un espace, mais seulement les routes qui permettent de relier des ordinateurs entre eux. Pareillement au monde géographique, le réseau routier a donc été créé avant les bâtiments, tandis que dans la ville numérique, c’est le World Wide Web, en tant que nouvel outil informatique, qui a permis la construction de l’espace urbain et de ses quartiers constitués de sites web.{{AutoCat}}
nvh4wwmjbma71tg9f4ac2xb3z1low1b
764275
764268
2026-04-21T20:58:04Z
Lionel Scheepmans
20012
764275
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Celui-ci fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. Le projet fut ensuite présenté lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' par son auteur [[w:fr:Michel Elie|Michel Elie]], apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. En témoignant d’une familiarité entre la création d’Internet et le fonctionnement de Wikipédia, cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci :
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Revenir sur ce sujet est l'occasion de citer un ouvrage intéressant, publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut être paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre réponse au paradoxe, il y a ensuite les propos tenus en 1992 par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales : « Nous récusons : rois, présidents et votes. Nous croyons : au consensus et aux programmes qui tournent. »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases qui permettent ainsi de croire que le mépris de la contre-culture des années 1960 envers la technique et la science a pu se transformer en un refus d’autorité et une recherche de consensus, dans le milieu informatique universitaire de 1990.
Ce qui ne fait aucun doute en revanche, c'est que le développement du réseau Internet fut le théâtre de conflits idéologiques importants. À ce propos, il est d'ailleurs intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car, à la suite d'un appel à des fonds privés pour financer d'importants changements d'infrastructure en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est ainsi devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dont l'usage est dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce contexte et parmi les 100 sites web [[w:_Liste_des_sites_web_les_plus_visités|les sites web les plus visités]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. En ce sens, le mouvement Wikimédia, au travers de son encyclopédie et de la fondation qui la supporte, représente l'expression la plus visible, à ce jour et sur le Web, de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une situation de survie, dans un espace numérique où seuls les projets commerciaux semblent maintenir le dessus. C'est là une nouvelle considération importante concernant le mouvement Wikimédia, mais elle ne clôture pas pour autant la liste des choses qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, cela a permis d'introduire le World Wide Web, qui fut un antécédent incontournable à la création de Wikipédia.{{AutoCat}}
j0gyyc22r81mk40k5yr85rnwjyetjr5
764343
764275
2026-04-22T06:39:26Z
Lionel Scheepmans
20012
764343
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce derner fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. Le projet fut ensuite présenté lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' par son auteur [[w:fr:Michel Elie|Michel Elie]], apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. En témoignant d’une familiarité entre la création d’Internet et le fonctionnement de Wikipédia, cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci :
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Revenir sur ce sujet est l'occasion de citer un ouvrage intéressant, publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut être paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre réponse au paradoxe, il y a ensuite les propos tenus en 1992 par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales : « Nous récusons : rois, présidents et votes. Nous croyons : au consensus et aux programmes qui tournent. »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases qui permettent ainsi de croire que le mépris de la contre-culture des années 1960 envers la technique et la science a pu se transformer en un refus d’autorité et une recherche de consensus, dans le milieu informatique universitaire de 1990.
Ce qui ne fait aucun doute en revanche, c'est que le développement du réseau Internet fut le théâtre de conflits idéologiques importants. À ce propos, il est d'ailleurs intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car, à la suite d'un appel à des fonds privés pour financer d'importants changements d'infrastructure en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est ainsi devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dont l'usage est dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce contexte et parmi les 100 sites web [[w:_Liste_des_sites_web_les_plus_visités|les sites web les plus visités]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. En ce sens, le mouvement Wikimédia, au travers de son encyclopédie et de la fondation qui la supporte, représente l'expression la plus visible, à ce jour et sur le Web, de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une situation de survie, dans un espace numérique où seuls les projets commerciaux semblent maintenir le dessus. C'est là une nouvelle considération importante concernant le mouvement Wikimédia, mais elle ne clôture pas pour autant la liste des choses qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, cela a permis d'introduire le World Wide Web, qui fut un antécédent incontournable à la création de Wikipédia.{{AutoCat}}
acb5hx8wgbe25z75rr6khdrc1rau2oy
764344
764343
2026-04-22T06:41:37Z
Lionel Scheepmans
20012
764344
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce dernier fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. L'une des premières présentations de leur projet fut réalisée lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' par son auteur [[w:fr:Michel Elie|Michel Elie]], apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. En témoignant d’une familiarité entre la création d’Internet et le fonctionnement de Wikipédia, cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci :
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Revenir sur ce sujet est l'occasion de citer un ouvrage intéressant, publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut être paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre réponse au paradoxe, il y a ensuite les propos tenus en 1992 par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales : « Nous récusons : rois, présidents et votes. Nous croyons : au consensus et aux programmes qui tournent. »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases qui permettent ainsi de croire que le mépris de la contre-culture des années 1960 envers la technique et la science a pu se transformer en un refus d’autorité et une recherche de consensus, dans le milieu informatique universitaire de 1990.
Ce qui ne fait aucun doute en revanche, c'est que le développement du réseau Internet fut le théâtre de conflits idéologiques importants. À ce propos, il est d'ailleurs intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car, à la suite d'un appel à des fonds privés pour financer d'importants changements d'infrastructure en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est ainsi devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dont l'usage est dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce contexte et parmi les 100 sites web [[w:_Liste_des_sites_web_les_plus_visités|les sites web les plus visités]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. En ce sens, le mouvement Wikimédia, au travers de son encyclopédie et de la fondation qui la supporte, représente l'expression la plus visible, à ce jour et sur le Web, de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une situation de survie, dans un espace numérique où seuls les projets commerciaux semblent maintenir le dessus. C'est là une nouvelle considération importante concernant le mouvement Wikimédia, mais elle ne clôture pas pour autant la liste des choses qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, cela a permis d'introduire le World Wide Web, qui fut un antécédent incontournable à la création de Wikipédia.{{AutoCat}}
7c063r9b2fm28aekdrpuo7qt1f0ea5i
764346
764344
2026-04-22T07:41:52Z
Lionel Scheepmans
20012
764346
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce dernier fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. L'une des premières présentations de leur projet fut réalisée lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. Dans son témoignage, [[w:fr:Michel Elie|Michel Elie]], cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment, et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci.
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Afin d'illustrer les idées véhiculées à cette époque, voici un paragraphe extrait d'un ouvrage publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut sembler paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre indication, il y a ensuite les propos tenus en 1992 par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales : « Nous récusons : rois, présidents et votes. Nous croyons : au consensus et aux programmes qui tournent. »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases qui permettent ainsi de croire que le mépris de la contre-culture des années 1960 envers la technique et la science a pu se transformer en un refus d’autorité et une recherche de consensus, dans le milieu informatique universitaire de 1990.
Ce qui ne fait aucun doute en revanche, c'est que le développement du réseau Internet fut le théâtre de conflits idéologiques importants. À ce propos, il est d'ailleurs intéressant de se demander à quoi ressemblerait Internet aujourd'hui, s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Car, à la suite d'un appel à des fonds privés pour financer d'importants changements d'infrastructure en novembre 1994, l’association sans but lucratif responsable de son accès, intitulée ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services]]'', décida de vendre ses activités à la société commerciale ''[[w:AOL|America Online, Inc]]'', pour la somme de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est ainsi devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dont l'usage est dominé par des sociétés commerciales parmi les plus riches au monde. Dans ce contexte et parmi les 100 sites web [[w:_Liste_des_sites_web_les_plus_visités|les sites web les plus visités]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. En ce sens, le mouvement Wikimédia, au travers de son encyclopédie et de la fondation qui la supporte, représente l'expression la plus visible, à ce jour et sur le Web, de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une situation de survie, dans un espace numérique où seuls les projets commerciaux semblent maintenir le dessus. C'est là une nouvelle considération importante concernant le mouvement Wikimédia, mais elle ne clôture pas pour autant la liste des choses qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, cela a permis d'introduire le World Wide Web, qui fut un antécédent incontournable à la création de Wikipédia.{{AutoCat}}
1co2xtetstb71il0o4ayi6aixk4feob
764349
764346
2026-04-22T08:45:16Z
Lionel Scheepmans
20012
764349
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce dernier fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], alors qu’ils travaillaient tous deux pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. L'une des premières présentations de leur projet fut réalisée lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après cette séparation, le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. La séparation entre les deux réseaux fut définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]]. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>. Rien de comparable donc, avec l’Internet développé au cours des années 1990, jusqu’à devenir ce vaste réseau informatique mondial que nous connaissons aujourd’hui.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992 et sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. Dans son témoignage, [[w:fr:Michel Elie|Michel Elie]], cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment, et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci.
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Afin d'illustrer les idées véhiculées à cette époque, voici un paragraphe extrait d'un ouvrage publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
Après cette lecture, il peut sembler paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie « utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également objets technologiques les plus en pointe grâce à l’influent Steward Brand, génial créateur d’un catalogue interactif, ancêtre analogique des [[w:Focus_group|groupes de discussions]] numériques qui émergeront des années plus tard »<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre indication, il y a ensuite les propos tenus en 1992, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet, par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet. Durant cette rencontre, ce chef de projet prononça ces deux phrases restées dans les annales<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref>. Nous récusons rois, présidents et votes. Nous croyons au consensus et aux programmes qui tournent<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases seulement, mais qui, dans le cadre du milieu informatique, permettent de croire que le mépris de la contre-culture envers la technique et la science s'est transformé en un refus d’autorité et une recherche de consensus.
Dans tous les cas, le développement du réseau Internet ne s'est pas fait sans conflits idéologiques importants. On peut d'ailleurs se demander aujourd'hui à quoi ressemblerait Internet s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Cela s'est passé en novembre 1994, lorsque l’association sans but lucratif ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services,]] chargée de g''érer les accès à Internet, a fait le choix de vendre ses activités. Cette décision faisait suite à un appel à des fonds privés pour financer d'importants changements dans l'infrastructure du réseau. Profitant de l'occasion, la société commerciale ''[[w:AOL|America Online]]'' a ainsi repris à son compte la gestion des connexions à Internet, après avoir effectué un versement de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dominé par des sociétés privées les plus riches au monde. Dans ce contexte et parmi les 100 [[w:_Liste_des_sites_web_les_plus_visités|sites web les plus visités au monde]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. Cela explique donc pourquoi le mouvement Wikimédia, via son encyclopédie et la fondation qui l'héberge, représente à ce jour, et dans l'espace web, l'expression la plus visible de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une mission perpétuée au sein d'un espace envahi par une culture marchande et capitaliste, entretenue par de grandes compagnies commerciales. C'est là une information importante qu'il faut retenir au sujet du mouvement Wikimédia. Elle ne clôture pas pour autant tout ce qu'il faut savoir au sujet des évènements qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, elle nous invite à découvrir l'histoire du World Wide Web, un espace numérique sans lequel la création de Wikipédia n'aurait jamais été possible.{{AutoCat}}
3266zthz6z9sm3tvhy1py7zkf53nsuf
764395
764349
2026-04-22T09:14:44Z
Lionel Scheepmans
20012
764395
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce dernier fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], quand ils travaillaient pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. L'une des premières présentations de leur projet fut d'ailleurs réalisée lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après une séparation définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]], le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>, ce qui n'a donc rien de comparable avec ce vaste réseau informatique mondial que nous connaissons aujourd’hui, et qui fut fortement développé au cours des années 1990.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992, sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. Dans son témoignage, [[w:fr:Michel Elie|Michel Elie]], cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment, et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci.
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Afin d'illustrer les idées véhiculées à cette époque, voici un paragraphe extrait d'un ouvrage publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
À la suite de cette lecture, il peut sembler paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également, objets technologiques les plus en pointe. Cela grâce notamment à l’influence de Steward Brand, le créateur d'un catalogue interactif, qui peut être considéré comme l'ancêtre analogique des groupes de discussions numériques apparus des années plus tard<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre indication, il y a ensuite les propos tenus en 1992, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet, par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet. Durant cette rencontre, ce chef de projet prononça des paroles<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales. « Nous récusons rois, présidents et votes. Nous croyons au consensus et aux programmes qui tournent »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases seulement, mais qui, dans le cadre du milieu informatique, permettent de croire que le mépris de la contre-culture envers la technique et la science, s'est transformé en un refus d’autorité et une recherche de consensus.
Dans tous les cas, le développement du réseau Internet ne s'est pas fait sans conflits idéologiques importants. On peut d'ailleurs se demander aujourd'hui à quoi ressemblerait Internet s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Cela s'est passé en novembre 1994, lorsque l’association sans but lucratif ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services,]] chargée de g''érer les accès à Internet, a fait le choix de vendre ses activités. Cette décision faisait suite à un appel à des fonds privés pour financer d'importants changements dans l'infrastructure du réseau. Profitant de l'occasion, la société commerciale ''[[w:AOL|America Online]]'' a ainsi repris à son compte la gestion des connexions à Internet, après avoir effectué un versement de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dominé par des sociétés privées les plus riches au monde. Dans ce contexte et parmi les 100 [[w:_Liste_des_sites_web_les_plus_visités|sites web les plus visités au monde]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. Cela explique donc pourquoi le mouvement Wikimédia, via son encyclopédie et la fondation qui l'héberge, représente à ce jour, et dans l'espace web, l'expression la plus visible de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une mission perpétuée au sein d'un espace envahi par une culture marchande et capitaliste, entretenue par de grandes compagnies commerciales. C'est là une information importante qu'il faut retenir au sujet du mouvement Wikimédia. Elle ne clôture pas pour autant tout ce qu'il faut savoir au sujet des évènements qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, elle nous invite à découvrir l'histoire du World Wide Web, un espace numérique sans lequel la création de Wikipédia n'aurait jamais été possible.{{AutoCat}}
cana1b7dficjsov7b61mg1f60g7i1o8
764396
764395
2026-04-22T09:15:50Z
Lionel Scheepmans
20012
764396
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>
L’[[w:fr : Histoire d'Internet|histoire du réseau Internet]] constitue un nouvel épisode captivant de la révolution numérique, sans lequel le mouvement Wikimédia n’aurait jamais pu émerger. D’un point de vue purement technique, ce réseau informatique a été mis au point dans les années 1970, avant l’adoption généralisée du protocole [[w:fr : Suite des protocoles Internet|TCP/IP]], toujours en usage à ce jour. Ce dernier fut inventé par [[w:Vint_Cerf|Vint Cerf]] et [[w:fr : Bob Kahn|Robert Elliot Kahn]], quand ils travaillaient pour la ''[[w:fr : Defense Advanced Research Projects Agency|Defense Advanced Research Projects Agency]]'', rattachée au département de la Défense américaine<ref name="Chemla">{{Ouvrage|langue=|auteur=Laurent Chemla|prénom1=Djilali|nom1=Benamrane|nom2=Biens publics à l'échelle mondiale|nom3=Coopération solidarité développement aux PTT|titre=Les télécommunications, entre bien public et marchandise|passage=73 & 63 (par ordre de citation)|lieu=Une histoire d'Internet|éditeur=ECLM (Charles Leopold Mayer)|date=2005|pages totales=|isbn=978-2-84377-111-8|oclc=833154536|lire en ligne=|consulté le=}}.</ref>. L'une des premières présentations de leur projet fut d'ailleurs réalisée lors d’une conférence organisée par l’[[w:fr : International Network Working Group|International Network Working Group]], une instance créée pour assurer la gouvernance mondiale du réseau informatique.
Sur base de ces informations, on peut penser qu’Internet a été créé par des militaires. Cependant, ''[[w:Une_contre-histoire_de_l'Internet|Une contre-histoire de l’Internet]]''<ref>{{Ouvrage|éditeur=Premieres Lignes Television|titre=Une contre-histoire de l'Internet|année=2013|auteur=[[w:Sylvain Bergère|]]}}</ref>, nous révèle que les créateurs et les premiers utilisateurs d’[[w:ARPANET|ARPANET]], considéré comme l’ancêtre d’Internet, étaient davantage des étudiants [[w:Hippies|hippies]] et amateurs de [[w:LSD|LSD]], que des militaires bien drillés. D’ailleurs, avant la standardisation du protocole TCP/IP, ARPANET fonctionnait depuis plus d’un an avec un autre protocole de transition intitulé [[w:Network_Control_Program_(Arpanet)|''Network Control Program'']]. Or, celui-ci avait été mis au point, en février 1969, par le [[w:fr : Network Working Group|''Network Working Group'']], un groupe informel d’étudiants rassemblés autour de [[w:Steve_Crocker|Steve Crocker]], lorsqu’il ne détenait encore qu’une simple licence.
[[Fichier:Internet_map_1024.jpg|alt=Nuage filandreux de lignes multicolores|vignette|<small>Figure 10. Carte partielle d’Internet, créée sur base des données d’opte.org en date du 15 juin 2005.</small>|gauche|300x300px]]
Bien que rarement cité dans l’histoire d’Internet, ce groupe a pourtant mis en place la procédure RFC, pour ''[[w:Request_for_comments|Request For Comments]],'' reconnue comme « l’un des symboles forts de la "culture technique" de l’Internet, marquée par l’égalitarisme, l’autogestion et la recherche collective de l’efficience »<ref name="Serres">{{Article|auteur=|prénom1=Alexandre|nom1=Serres|prénom2=Christian|nom2=Le Moënne|prénom3=Jean-Max|nom3=Noyer|nom4=|titre=Aux sources d'internet : l'émergence d'Arpanet : exploration du processus d'émergence d'une infrastructure informationnelle : description des trajectoires des acteurs et actants, des filières et des réseaux constitutifs de la naissance d'Arpanet : problèmes critiques et épistémologiques posés par l'histoire des innovations|périodique=Thèse de doctorat|éditeur=Université Rennes 2|date=2000|issn=|lire en ligne=https://tel.archives-ouvertes.fr/tel-00312005/document|pages=481 & 488 (par ordre de citation)}}.</ref>. Soit trois principes et une procédure, qui aujourd’hui encore sont appliqués sur le site Méta-Wiki, dans lequel s'organise la gestion communautaire du mouvement Wikimédia. Cela alors qu'au sein des projets pédagogiques, d’autres processus similaires de recherche de consensus ont fait leur apparition.
Il faut savoir ensuite que les liens entre ARPANET et l’armée ont disparu avec l’apparition du [[w:en : MILNET|MILNET]], un réseau entièrement dédié aux activités militaires, qui a ensuite été rebaptisé [[w:en:NIPRNet|NIPRNet]], pour Non-classified Internet Protocol Router Network, en 1990. Après une séparation définitive en 1983, précisément l’année où [[w:Richard_Stallman|Richard Stallman]] postait sa demande d’aide pour le [[w:Projet_GNU|projet GNU]], le réseau ARPANET resta uniquement dédié à la recherche et au développement<ref>{{Ouvrage|langue=|auteur=|prénom1=Stephen|nom1=Denneti|titre=ARPANET Information Brochure|passage=4|lieu=|éditeur=Defense Communications Agency|date=1978|pages totales=46|isbn=|oclc=476024876|lire en ligne=https://web.archive.org/web/20200710174908/https://apps.dtic.mil/dtic/tr/fulltext/u2/a164353.pdf}}.</ref>. À cette époque, le réseau ne comprenait pas plus de 600 machines connectées<ref>{{Ouvrage|langue=|auteur=|prénom1=Solange|nom1=Ghernaouti-Hélie|prénom2=Arnaud|nom2=Dufour|titre=Internet|passage=|lieu=|éditeur=Presses universitaires de France|date=2012|pages totales=|isbn=978-2-13-058548-0|oclc=795497443|lire en ligne=|consulté le=}}.</ref>, ce qui n'a donc rien de comparable avec ce vaste réseau informatique mondial que nous connaissons aujourd’hui, et qui fut fortement développé au cours des années 1990.
Pour en assurer l’entretien technique, une [[w:Organisation_non_gouvernementale|organisation non gouvernementale]], a été créée en 1992, sous l'appellation d’''[[w:fr : Internet Society|Internet Society]]''. Celle-ci devait aussi veiller au respect des valeurs fondamentales liées au bon fonctionnement du réseau<ref>{{Lien web|langue=|auteur=Étienne Combier|titre=Les leçons de l’Internet Society pour sauver la Toile|url=https://web.archive.org/web/20201024101959/https://www.lesechos.fr/2017/09/les-lecons-de-linternet-society-pour-sauver-la-toile-182263|site=Les Echos|éditeur=|date=2017-09-19|consulté le=}}.</ref>. Car avant d'atteindre des milliards d’appareils connectés en réseau, il a d’abord fallu réglementer les nombreuses [[w:Dorsale Internet|dorsales internet]] intercontinentales, sans lesquelles la transmission du protocole TCP/IP partout dans le monde n'aurait pas été possible.
Pour en revenir à l’état d’esprit des créateurs d'Internet, un article intitulé ''Quarante ans après : mais qui donc créa l’internet ?'' apporte un éclairage particulièrement intéressant au sujet des liens que l'on peut établir entre le mouvement Wikimédia et l'[[w:Histoire_d'Internet|histoire d'Internet]]. Dans son témoignage, [[w:fr:Michel Elie|Michel Elie]], cet ingénieur en informatique, membre du ''Network Working Group'' cité précédemment, et responsable de l’[[w:fr : Observatoire des usages de l'Internet|Observatoire des Usages de l’Internet]], nous explique effectivement ceci.
<blockquote>
Le succès de l’internet, nous le devons aux bons choix initiaux et à la dynamique qui en est résultée : la collaboration de dizaines de milliers d’étudiants, ou de bénévoles apportant leur expertise, tels par exemple ces centaines de personnes qui enrichissent continuellement des encyclopédies en ligne telles que Wikipédia.''<ref>{{Lien web|langue=|auteur=Michel Elie|titre=Quarante ans après : mais qui donc créa l'internet ?|url=https://web.archive.org/web/20200131180536/https://vecam.org/archives/article1123.html|site=Vecam|lieu=|date=2009|consulté le=}}.</ref>''
</blockquote>
Au courant des années 1990, le milieu informatique universitaire semblait donc toujours fortement imprégné des idéaux de la [[w:Contre-culture des années 1960|contre-culture des années 1960]], produit par les [[w:Baby_boomer|''baby boomers'']] dans le contexte de la [[w:Guerre_du_Vietnam|guerre du Vietnam]]. Afin d'illustrer les idées véhiculées à cette époque, voici un paragraphe extrait d'un ouvrage publié en 1970 et intitulé ''Vers une contre-culture : Réflexions sur la société technocratique et l’opposition de la jeunesse''<ref>{{Ouvrage|langue=|prénom1=Theodore|nom1=Roszak|prénom2=Claude|nom2=Elsen|titre=Vers une contre-culture. Réflexions sur la société technocratique et l'opposition de la jeunesse|passage=266-267|lieu=Paris|éditeur=Stock|date=1970|pages totales=318|isbn=978-2-234-01282-0|oclc=36236326}}.</ref>. Dans celui-ci, [[w:fr : Theodore Roszak|Théodore Roszak]] explique que :
<blockquote>
Le projet essentiel de notre contre-culture : proclamer un nouveau ciel et une nouvelle terre, si vastes, si merveilleux que les prétentions démesurées de la technique soient réduites à n’occuper dans la vie humaine qu’une place inférieure et marginale. Créer et répandre une telle conception de la vie n’implique rien de moins que l’acceptation de nous ouvrir à l’imagination visionnaire. Nous devons être prêts à soutenir ce qu’affirment des personnes telles que [[w:fr : William Blake|Blake]], à savoir que certains yeux ne voient pas le monde comme le voient le regard banal ou l’œil scientifique, mais le voient transformé, dans une lumière éclatante et, ce faisant, le voient tel qu’il est vraiment.
</blockquote>
À la suite de cette lecture, il peut sembler paradoxal de penser qu’une contre-culture, voyant la technique comme « inférieure » et assimilant la science au « banal », puisse avoir un lien avec le milieu scientifique universitaire qui fut à l'origine d'Internet. Cependant, une réponse à cette énigme fut apportée par [[w:Fred_Turner_(professeur)|Fred Turner]], par la publication de son livre intitulé : « ''Aux sources de l’utopie numérique : De la contre-culture à la cyberculture, [[w:Stewart_Brand|Stewart Brand]], un homme d’influence »''<ref>{{Ouvrage|langue=fr|prénom1=Fred|nom1=Turner|titre=Aux sources de l'utopie numérique: De la contre-culture à la cyberculture, Stewart Brand, un homme d'influence|éditeur=C & F Éditions|date=2021-07-07|isbn=978-2-37662-032-7}}.</ref>.
Grâce à cet ouvrage, on découvre en effet que le mouvement Hippie utilisera tout ce qui était à sa disposition à l’époque pour parvenir à ses fins : LSD, spiritualités alternatives, mais également, objets technologiques les plus en pointe. Cela grâce notamment à l’influence de Steward Brand, le créateur d'un catalogue interactif, qui peut être considéré comme l'ancêtre analogique des groupes de discussions numériques apparus des années plus tard<ref>{{Lien web|auteur=Guillaume de Lamérie|titre=Aux sources de l’utopie numérique, de la contre-culture à la cyberculture|url=https://web.archive.org/web/20211021183032/https://www.afis.org/Aux-sources-de-l-utopie-numerique|site=Association française pour l’Information Scientifique|éditeur=|date=18 septembre 2013|consulté le=}}.</ref>.
Comme autre indication, il y a ensuite les propos tenus en 1992, lors d’une plénière de la 24ᵉ réunion du groupe de travail sur l’ingénierie Internet, par [[w:fr : David D. Clark|David D. Clark]], un autre pionnier d’Internet. Durant cette rencontre, ce chef de projet prononça des paroles<ref>{{Article|prénom1=Andrew L.|nom1=Russell|titre='Rough Consensus and Running Code' and the Internet-OSI Standards War|périodique=IEEE Annals Hist. Comput. IEEE Annals of the History of Computing|volume=28|numéro=3|date=2006|issn=1058-6180|pages=48–61}}.</ref> restées dans les annales. « Nous récusons rois, présidents et votes. Nous croyons au consensus et aux programmes qui tournent »<ref>Texte original avant sa traduction par www.deepl.com/translator : « ''We reject: kings, presidents and voting. We believe: in rough consensus and running code »''</ref>. Deux phrases seulement, mais qui, dans le cadre du milieu informatique, permettent de croire que le mépris de la contre-culture envers la technique et la science, s'est transformé en un refus d’autorité et une recherche de consensus.
Dans tous les cas, le développement du réseau Internet ne s'est pas fait sans conflits idéologiques importants. On peut d'ailleurs se demander aujourd'hui à quoi ressemblerait Internet s'il n'avait jamais été [[w:en:Commercialization_of_the_Internet|commercialisé]]<ref>{{Ouvrage|langue=en|prénom1=Shane|nom1=Greenstein|titre=How the Internet Became Commercial: Innovation, Privatization, and the Birth of a New Network|passage=79|éditeur=Princeton University Press|date=2017-09-26|isbn=978-0-691-17839-4|consulté le=2025-12-27}}</ref>. Cela s'est passé en novembre 1994, lorsque l’association sans but lucratif ''[[w:en:Advanced_Network_and_Services|Advanced Network and Services,]] chargée de g''érer les accès à Internet, a fait le choix de vendre ses activités. Cette décision faisait suite à un appel à des fonds privés pour financer d'importants changements dans l'infrastructure du réseau. Profitant de l'occasion, la société commerciale ''[[w:AOL|America Online]]'' a ainsi repris à son compte la gestion des connexions à Internet, après avoir effectué un versement de 35 millions de dollars<ref>{{Lien web|titre=ANS sold to America On-line|url=https://web.archive.org/web/20110927083123/http://www.merit.edu/mail.archives/mjts/1994-11/msg00023.html|site=www.merit.edu|auteur=Jeff.Ogden}}</ref>.
Trente ans plus tard, Internet est devenu ce réseau que nous expérimentons aujourd'hui, à savoir, un réseau dominé par des sociétés privées les plus riches au monde. Dans ce contexte et parmi les 100 [[w:_Liste_des_sites_web_les_plus_visités|sites web les plus visités au monde]], seul le [[w:Nom_de_domaine|nom de domaine]] Wikipédia appartient à une organisation non lucrative<ref>{{Lien web|titre=Top 100 Most Visited Websites Worldwide (August 2025)|url=https://web.archive.org/web/20250923022332/https://www.similarweb.com/blog/research/market-research/most-visited-websites/|auteur=Similarweb}}</ref>. Cela explique donc pourquoi le mouvement Wikimédia, via son encyclopédie et la fondation qui l'héberge, représente à ce jour, et dans l'espace web, l'expression la plus visible de la philosophie des pionniers d’Internet.
Plus qu'un héritage, cette situation peut être vue comme une mission perpétuée au sein d'un espace envahi par une culture marchande et capitaliste. C'est là une information importante qu'il faut retenir au sujet du mouvement Wikimédia. Elle ne clôture pas pour autant tout ce qu'il faut savoir au sujet des évènements qui ont permis la création d’une encyclopédie mondiale, libre et collaborative. En revanche, elle nous invite à découvrir l'histoire du World Wide Web, un espace numérique sans lequel la création de Wikipédia n'aurait jamais été possible.{{AutoCat}}
b2j1gym2mvj4vn1xde5gg4weitntgil
Le mouvement Wikimédia/Le World Wide Web
0
83388
764397
757341
2026-04-22T10:06:36Z
Lionel Scheepmans
20012
764397
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>Maintenant que le lien entre la création d'Internet et le mouvement Wikimédia est établi, découvrons à présent l'application la plus connue du réseau, que l'on nomme le ''[[w:World Wide Web|World Wide Web]]'', ou plus simplement ''« Web »''. [[w:fr : Tim Berners-Lee|Tim Berners-Lee]] en fut l’inventeur, lorsqu’il était encore actif à l'[[w:Organisation_européenne_pour_la_recherche_nucléaire|Organisation européen pour la recherche nucléaire]]. C'est lui qui a eu l’idée de créer un espace d’échange public par l’intermédiaire d'Internet. Et pour y parvenir, il mit au point le logiciel « [[w:fr:WorldWideWeb|''WorldWideWeb'']] », rebaptisé Nexus par la suite afin d’éviter toute confusion avec l’expression ''World Wide Web,'' apparue ultérieurement<ref>{{Lien web|langue=|auteur=W3C|titre=Tim Berners-Lee : WorldWideWeb, the first Web client|url=https://web.archive.org/web/20201104024350/http://www.w3.org/People/Berners-Lee/WorldWideWeb.html|site=|consulté le=}}.</ref>[[Fichier:Sir Tim Berners-Lee (cropped).jpg|vignette|<small>Figure 11. Tim Berners-Lee en 2014.</small>]]
Grâce à un système d’indexation appelé [[w:Hypertexte|hypertexte]], ce programme informatique a permis de produire et connecter des espaces numériques intitulés sites Web. Ceux-ci sont composés de pages web, hébergées sur des ordinateurs distants, mais connectés entre eux via le réseau Internet. Pour permettre ce type de connexion, Berners-Lee mit au point le ''[[w:fr : Hypertext Transfer Protocol|Hypertext Transfer Protocol]]'' ou HTTP, un nouveau protocole de communication simple en soi, mais dont la mise en œuvre technique est compliquée.
Pour veiller au bon fonctionnement et au bon usage de l'espace web, des règles de standardisation ont tout d'abord été édictées par l’association ''[[w:fr : Internet Society|Internet Society]]''. Après quoi, Berners-Lee fonda le [[w:W3C|W3C]], un consortium international dont la devise est : « un seul Web partout et pour tous »<ref>{{Lien web|langue=|auteur=W3C|titre=La mission du W3C|url=https://web.archive.org/web/20201031040456/https://www.w3c.fr/a-propos-du-w3c-france/la-mission-du-w3c/|site=|date=|consulté le=}}.</ref>. Si ce slogan nous apparaît très naturel aujourd’hui, il faut toutefois savoir que l'espace Web a bien failli être géré séparément par des acteurs commerciaux, avec tous les droits d'accès que cela aurait pu engendrer.
À partir du trente avril 1993, jour du dépôt du logiciel WorldWideWeb dans le [[Le domaine public|domaine public]] par [[w:Robert Cailliau|Robert Cailliau]], un collègue de Berners-Lee chargé de la promotion de son projet, un tel scénario était en effet possible. Sauf qu'après le départ de Berners-Lee, devenu président du W3C, [[w:François Flückiger|François Flückiger]], qui avait repris son poste au sein du [[w:Organisation_européenne_pour_la_recherche_nucléaire|CERN]]<ref>{{Ouvrage|auteur1=James Gillies|auteur2=Robert Cailliau|titre=How the Web Was Born – The Story of the World Wide Web|éditeur=Oxford University Press|date=septembre 2000|pages totales=372|isbn=978-0-19-286207-5}}.</ref>, eut la présence d'esprit de réagir à temps. Selon le livre ''Alexandria'' qui parcourt l'histoire de Robert Caillau''<ref>{{Ouvrage|langue=|auteur=|prénom1=Quentin|nom1=Jardon|titre=Alexandria : les pionniers oubliés du web : récit|passage=154|lieu=Paris|éditeur=Gallimard|date=2019|pages totales=|isbn=978-2-07-285287-9|oclc=1107518440}}.</ref>'', voici ce qui aurait pu se passer si le code de l’éditeur HTML n'avait finalement pas été placé sous licence libre.
<blockquote>
La philanthropie de Robert, c’est très sympa, mais ça expose le Web à d’horribles dangers. Une entreprise pourrait s’emparer du code source, corriger un minuscule bug, s’approprier le « nouveau » logiciel et enfin faire payer une licence à ses utilisateurs. L’ogre Microsoft, par exemple, serait du genre à flairer le bon plan pour écraser son ennemi Macintosh. Les détenteurs d’un PC devraient alors débourser un certain montant pour profiter des fonctionnalités du Web copyrighté Microsoft. Les détenteurs d’un Macintosh, eux, navigueraient sur un Web de plus en plus éloigné de celui vendu par Bill Gates, d’abord gratuit peut-être, avant d’être soumis lui aussi à une licence.
</blockquote>
Face à un tel scénario, nous découvrons de nouveau à quel point le concept de licence libre a fondamentalement changé le cours de la révolution numérique. Sans cela, nos expériences et nos usages de l'espace numérique auraient été totalement différents. L'utopie Wikipédia, par exemple, n'aurait certainement pas vu le jour, en raison de l'éclatement des espaces numériques et des coûts d'accès auxquels seraient confrontés les bénévoles qui ont construit le projet. Quoi qu'il en soit et au niveau technique, une fois l'espace web apparu, il ne restait plus que l'arrivée des plateformes wiki pour permettre la création d'une encyclopédie collaborative au format numérique.{{AutoCat}}
fz5p4n0c7k6qgk4887mawqcf13661v2
764399
764397
2026-04-22T10:17:48Z
Lionel Scheepmans
20012
764399
wikitext
text/x-wiki
<noinclude>{{Le mouvement Wikimédia}}</noinclude>Maintenant que le lien entre la création d'Internet et le mouvement Wikimédia est établi, découvrons à présent l'application la plus connue du réseau, que l'on nomme le ''[[w:World Wide Web|World Wide Web]]'', ou plus simplement ''« Web »''. C'est [[w:fr : Tim Berners-Lee|Tim Berners-Lee]] qui en fut l’inventeur, lorsqu’il était encore actif à l'[[w:Organisation_européenne_pour_la_recherche_nucléaire|Organisation européen pour la recherche nucléaire]]. Il avait pour idée de créer un espace d’échange public par l’intermédiaire d'Internet, et pour y parvenir, il mit au point le logiciel « [[w:fr:WorldWideWeb|''WorldWideWeb'']] », rebaptisé Nexus pour éviter toute confusion avec le ''World Wide Web''<ref>{{Lien web|langue=|auteur=W3C|titre=Tim Berners-Lee : WorldWideWeb, the first Web client|url=https://web.archive.org/web/20201104024350/http://www.w3.org/People/Berners-Lee/WorldWideWeb.html|site=|consulté le=}}.</ref>[[Fichier:Sir Tim Berners-Lee (cropped).jpg|vignette|<small>Figure 11. Tim Berners-Lee en 2014.</small>]]
Grâce à un système d’indexation appelé [[w:Hypertexte|hypertexte]], ce programme informatique a permis de produire et de connecter des espaces numériques intitulés sites Web. Ceux-ci sont composés de pages web, hébergées sur des ordinateurs distants, mais connectés entre eux au travers du réseau Internet. Pour permettre ce type de connexion, Berners-Lee mit au point le ''[[w:fr : Hypertext Transfer Protocol|Hypertext Transfer Protocol]]'' ou HTTP, un nouveau protocole de communication simple en soi, mais dont la mise en œuvre technique est compliquée.
Pour veiller au bon fonctionnement et au bon usage de l'espace web, des règles de standardisation ont tout d'abord été édictées par l’association ''[[w:fr : Internet Society|Internet Society]]''. Après quoi, Berners-Lee fonda le [[w:W3C|W3C]], un consortium international dont la devise est : « un seul Web partout et pour tous »<ref>{{Lien web|langue=|auteur=W3C|titre=La mission du W3C|url=https://web.archive.org/web/20201031040456/https://www.w3c.fr/a-propos-du-w3c-france/la-mission-du-w3c/|site=|date=|consulté le=}}.</ref>. Si ce slogan nous apparaît très naturel aujourd’hui, il faut toutefois savoir que l'espace Web a bien failli être géré séparément par des acteurs commerciaux, avec tous les droits d'accès que cela aurait pu engendrer.
À partir du trente avril 1993, jour du dépôt du logiciel WorldWideWeb dans le [[Le domaine public|domaine public]] par [[w:Robert Cailliau|Robert Cailliau]], un collègue de Berners-Lee chargé de la promotion de son projet, un tel scénario était en effet possible. Sauf qu'après le départ de Berners-Lee, devenu président du W3C, [[w:François Flückiger|François Flückiger]], qui avait repris son poste au sein du [[w:Organisation_européenne_pour_la_recherche_nucléaire|CERN]]<ref>{{Ouvrage|auteur1=James Gillies|auteur2=Robert Cailliau|titre=How the Web Was Born – The Story of the World Wide Web|éditeur=Oxford University Press|date=septembre 2000|pages totales=372|isbn=978-0-19-286207-5}}.</ref>, eut la présence d'esprit de réagir à temps. Selon le livre ''Alexandria'' qui parcourt l'histoire de Robert Caillau''<ref>{{Ouvrage|langue=|auteur=|prénom1=Quentin|nom1=Jardon|titre=Alexandria : les pionniers oubliés du web : récit|passage=154|lieu=Paris|éditeur=Gallimard|date=2019|pages totales=|isbn=978-2-07-285287-9|oclc=1107518440}}.</ref>'', voici ce qui aurait pu se passer si le code de l’éditeur HTML n'avait finalement pas été placé sous licence libre.
<blockquote>
La philanthropie de Robert, c’est très sympa, mais ça expose le Web à d’horribles dangers. Une entreprise pourrait s’emparer du code source, corriger un minuscule bug, s’approprier le « nouveau » logiciel et enfin faire payer une licence à ses utilisateurs. L’ogre Microsoft, par exemple, serait du genre à flairer le bon plan pour écraser son ennemi Macintosh. Les détenteurs d’un PC devraient alors débourser un certain montant pour profiter des fonctionnalités du Web copyrighté Microsoft. Les détenteurs d’un Macintosh, eux, navigueraient sur un Web de plus en plus éloigné de celui vendu par Bill Gates, d’abord gratuit peut-être, avant d’être soumis lui aussi à une licence.
</blockquote>
Face à un tel scénario, nous découvrons de nouveau à quel point le concept de licence libre a fondamentalement changé le cours de la révolution numérique. Sans cela, nos expériences et nos usages de l'espace numérique auraient été totalement différents. L'utopie Wikipédia, par exemple, n'aurait certainement pas vu le jour, en raison de l'éclatement des espaces numériques et des coûts d'accès auxquels seraient confrontés les bénévoles qui ont construit le projet. Quoi qu'il en soit, et au niveau technique, une fois l'espace web apparu, il ne manquait plus qu'une chose pour permettre la création d'une encyclopédie collaborative au format numérique. C'était l'apparition des plateformes wiki.{{AutoCat}}
s1axw3qvwovize1kn4mi5j79vcpf2ux
Introduire la biodiversité dans la construction et l'urbanisme/Biodiversité dans l'environnement bâti : de quoi parlons nous ?/Microflore et microbiote
0
83827
764245
2026-04-21T16:27:45Z
Lamiot
1916
complément cf microbiotes
764245
wikitext
text/x-wiki
Des études récentes ont montré qu'il existe des liens forts entre le microbiote humain (microbiote cutané notamment) et l'équivalent d'un « microbiote du bâtiment » ; L'habitat semble fonctionner comme un ''écosystème microbien partagé'', où les occupants humains influencent fortement les communautés microbiennes intérieures et inversement. Ceci n'est pas vraiment surprenant étant donné que les humains passent près de 90 % de leur vie dans des environnements bâtis.
Ces interactions soulèvent des enjeux jusqu'alors ignorés, mais peut être majeurs pour l’urbanisme sain (encore à définir ou redéfinir car les approches hyper-hygiénistes s'avèrent contre-productives voire dangereuses) et pour la conception des bâtiments et des villes, qui doivent favoriser des environnements intérieurs sains, ventilés mais non stériles, favorables à une biodiversité microbienne bénéfique et, tant que possible, défavorable aux microbes pathogènes. Dans une perspective ''[[w:fr:One Health|One Health]]'', comprendre ces dynamiques permet d’intégrer la santé humaine, la qualité de l’air intérieur et la soutenabilité des espaces bâtis dans une même approche écologique.
== Similitudes entre le microbiote humain et le microbiote du bâtiment ==
Le '''microbiote du bâtiment''' désigne ici l’ensemble des micro-organismes (bactéries, champignons, virus) présents dans nos environnements intérieurs. Des chercheurs ont récemment montré qu’il présente de fortes analogies avec le '''microbiote humain''', a priori en raison des échanges constants entre les occupants et leur habitat. La présence de chats, chiens, oiseaux, etc peut aussi le moduler.
De même que le bébé humain acquiert l'essentiel de son microbiote de sa mère et de son environnement après la naissance, on constate que les bâtiments neufs acquièrent égalemnet, progressivement, leur microbiote, passant d’une communauté dominée par l’extérieur à une communauté de plus en plus influencée par la présence humaine après la première ocupation du lieu. Une fois le bâtiment occupé, la richesse et la diversité bactérienne diminuent nettement, tandis que les microbes associés à l’humain (dont ''[[w:Escherichia|Escherichia]], [[w:Pseudomonas|Pseudomonas]], [[w:Klebsiella|Klebsiella]]'') deviennent plus abondants, sous l’effet des interventions humaines et de la sélection environnementale intérieure. L’étude montre que des facteurs architecturaux comme la ventilation, le débit d’air, l’humidité et la température influencent fortement cette transition, ouvrant la voie à une gestion du microbiote intérieur par le design et l’exploitation des bâtiments<ref>{{Article |langue=en |prénom1=Gregory R. |nom1=Young |prénom2=Angela |nom2=Sherry |prénom3=Darren L. |nom3=Smith |titre=Built environment microbiomes transition from outdoor to human-associated communities after construction and commissioning |périodique=www.nature.com |volume=13 |numéro=1 |pages=15854 |date=2023-09-22 |issn=2045-2322 |doi=10.1038/s41598-023-42427-0 |lire en ligne=https://www.nature.com/articles/s41598-023-42427-0 |consulté le=2026-04-21}}</ref>.
=== Origine humaine majoritaire des micro-organismes intérieurs ===
Des études pionnières menées aux USA, dont par le biologiste '''Jack A. Gilbert''' dans le cadre du Home Microbiome Project ont montré que la composition microbienne d’un logement reflète rapidement celle de ses occupants<ref>Jack A. Gilbert et al., ''Microbial ecology of the home environment'', Proceedings of the Royal Society B, 2014.</ref>.
Selon ces travaux, la majorité des bactéries retrouvées sur les surfaces intérieures proviennent de la peau, de la bouche ou du système respiratoire humain.
=== Similarités structurelles entre microbiotes ===
Les deux microbiotes (celui du bâtiment, et celui des habitants) partagent plusieurs caractéristiques :
* une forte proportion de bactéries issues des phyla '''Firmicutes''' et '''Actinobacteria''', typiques du [[w:fr:microbiote cutané humain|microbiote cutané humain]]<ref>H. Lax et al., ''Longitudinal analysis of microbial interactions between humans and the indoor environment'', Science, 2014.</ref> ;
* une dynamique influencée par les comportements humains (fréquentation des pièces, ventilation, type et fréquence de nettoyage) ; par exemple, Kembel et al. ont montré en 2012 que les pièces ventilées mécaniquement abritent des communautés bactériennes moins diversifiées, et plus riches en microbes associés à l’humain — parfois proches de pathogènes — tandis que les pièces ventilées par l'ouverture de portes ou fenêtres présentent une composition intermédiaire entre l’extérieur et les espaces mécaniquement ventilés. Le design architectural et les conditions intérieures (débit d’air, humidité, température) peuvent donc être utilisés pour orienter la composition du microbiome intérieur, avec des implications directes pour la santé humaine et la gestion des risques dans les environnements bâtis encore à définir.
* une organisation en communautés microbiennes stables mais modulables selon les conditions environnementales (humidité, température, matériaux)<ref>{{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}</ref>.
=== Influence des matériaux et des conditions intérieures ===
Les travaux de la microbiologiste '''Jessica Green''' (Université de l'Oregon) ont montré que les bâtiments fonctionnent comme des écosystèmes particuliers, où les matériaux, la ventilation et l’architecture influencent plus ou moins saisonnièrement la composition microbienne du lieu<ref>Jessica L. Green et al., ''Buildings, microbiomes, and health'', Nature Reviews Microbiology, 2017.</ref>.
Cependant, même dans des environnements très différents, une part importante du microbiote intérieur reste d’origine humaine. Ceci explique les similitudes observées avec le microbiote cutané et respiratoire.
=== Transferts bidirectionnels entre humains et bâtiments ===
Les échanges microbiens entre humains et bâtiments sont '''bidirectionnels''' :
* les occupants déposent des micro-organismes sur les surfaces ;
* les surfaces et l’air intérieur peuvent en retour influencer le microbiote humain, notamment cutané et respiratoire<ref>M. Dannemiller et al., ''Indoor microbial communities: ecology and health effects'', Annual Review of Public Health, 2017.</ref>.
Cette relation réciproque conduit certains chercheurs à considérer les bâtiments comme une « extension écologique » du microbiote humain.
=== Approches récentes et implications ===
Les recherches récentes en '''microbiologie du bâti''' (''building microbiome science'') soulignent l’importance de concevoir des environnements intérieurs favorisant une diversité microbienne bénéfique, dont en utilisant la ventilation naturelle, les matériaux poreux, et par un usage parcimonieux et raisonné des biocides (eau de javel notamment).
Ces travaux s’inscrivent dans une perspective de [[w:santé publique|santé publique]], en lien avec la notion d’'''[[w:exposome|exposome]]''' (qui intègre l’ensemble des expositions environnementales influençant la santé humaine, ou animale pour les animaux domestiques). Néanmoins, on ne sait pas encore définir ce qu’est un environnement intérieur “sain”, ni comment modifier de manière fiable la ventilation, les matériaux ou la conception et l'usage des bâtiments pour influencer positivement ces communautés microbiennes.
Un rapport<ref>{{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}</ref> du NASEM (National Academies of Sciences, Engineering, and Medicine), intitulé ''Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings'', a en 2017, souligné la nécessité d’une [[w:Approche écosystémique|approche écosystémique]] et interdisciplinaire pour comprendre ces interactions complexes et orienter des décisions éclairées en matière d’habitat, d’urbanisme et de santé environnementale.
== Bibliographie ==
* {{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}
* {{Article |prénom1=Simon |nom1=Lax |prénom2=Daniel P. |nom2=Smith |prénom3=Jarrad |nom3=Hampton-Marcell |prénom4=Sarah M. |nom4=Owens |titre=Longitudinal analysis of microbial interaction between humans and the indoor environment |périodique=science.org (Atypon) |volume=345 |numéro=6200 |pages=1048–1052 |date=2014-08-29 |pmid=25170151 |pmcid=4337996 |doi=10.1126/science.1254529 |lire en ligne=https://www.science.org/doi/abs/10.1126/science.1254529 |consulté le=2026-04-21}}
* {{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}
== Références ==
jptbavgpe9iswafqvpponh7wngyi6kl
764247
764245
2026-04-21T16:34:11Z
Lamiot
1916
complément
764247
wikitext
text/x-wiki
Des études récentes ont montré qu'il existe des liens forts entre le microbiote humain (microbiote cutané notamment) et l'équivalent d'un « microbiote du bâtiment » ; L'habitat semble fonctionner comme un ''écosystème microbien partagé'', où les occupants humains influencent fortement les communautés microbiennes intérieures et inversement. Ceci n'est pas vraiment surprenant étant donné que les humains passent près de 90 % de leur vie dans des environnements bâtis.
Ces interactions soulèvent des enjeux jusqu'alors ignorés, mais peut être majeurs pour l’urbanisme sain (encore à définir ou redéfinir car les approches hyper-hygiénistes s'avèrent contre-productives voire dangereuses) et pour la conception des bâtiments et des villes, qui doivent favoriser des environnements intérieurs sains, ventilés mais non stériles, favorables à une biodiversité microbienne bénéfique et, tant que possible, défavorable aux microbes pathogènes. Dans une perspective ''[[w:fr:One Health|One Health]]'', comprendre ces dynamiques permet d’intégrer la santé humaine, la qualité de l’air intérieur et la soutenabilité des espaces bâtis dans une même approche écologique.
== Similitudes entre le microbiote humain et le microbiote du bâtiment ==
Le '''microbiote du bâtiment''' désigne ici l’ensemble des micro-organismes (bactéries, champignons, virus) présents dans nos environnements intérieurs. Des chercheurs ont récemment montré qu’il présente de fortes analogies avec le '''microbiote humain''', a priori en raison des échanges constants entre les occupants et leur habitat. La présence de chats, chiens, oiseaux, etc peut aussi le moduler.
De même que le bébé humain acquiert l'essentiel de son microbiote de sa mère et de son environnement après la naissance, on constate que les bâtiments neufs acquièrent égalemnet, progressivement, leur microbiote, passant d’une communauté dominée par l’extérieur à une communauté de plus en plus influencée par la présence humaine après la première ocupation du lieu. Une fois le bâtiment occupé, la richesse et la diversité bactérienne diminuent nettement, tandis que les microbes associés à l’humain (dont ''[[w:Escherichia|Escherichia]], [[w:Pseudomonas|Pseudomonas]], [[w:Klebsiella|Klebsiella]]'') deviennent plus abondants, sous l’effet des interventions humaines et de la sélection environnementale intérieure. L’étude montre que des facteurs architecturaux comme la ventilation, le débit d’air, l’humidité et la température influencent fortement cette transition, ouvrant la voie à une gestion du microbiote intérieur par le design et l’exploitation des bâtiments<ref>{{Article |langue=en |prénom1=Gregory R. |nom1=Young |prénom2=Angela |nom2=Sherry |prénom3=Darren L. |nom3=Smith |titre=Built environment microbiomes transition from outdoor to human-associated communities after construction and commissioning |périodique=www.nature.com |volume=13 |numéro=1 |pages=15854 |date=2023-09-22 |issn=2045-2322 |doi=10.1038/s41598-023-42427-0 |lire en ligne=https://www.nature.com/articles/s41598-023-42427-0 |consulté le=2026-04-21}}</ref>.
=== Origine humaine majoritaire des micro-organismes intérieurs ===
Des études pionnières menées aux USA, dont par le biologiste '''Jack A. Gilbert''' dans le cadre du Home Microbiome Project ont montré que la composition microbienne d’un logement reflète rapidement celle de ses occupants<ref>Jack A. Gilbert et al., ''Microbial ecology of the home environment'', Proceedings of the Royal Society B, 2014.</ref>.
Selon ces travaux, la majorité des bactéries retrouvées sur les surfaces intérieures proviennent de la peau, de la bouche ou du système respiratoire humain.
=== Similarités structurelles entre microbiotes ===
Les deux microbiotes (celui du bâtiment, et celui des habitants) partagent plusieurs caractéristiques :
* une forte proportion de bactéries issues des phyla '''Firmicutes''' et '''Actinobacteria''', typiques du [[w:fr:microbiote cutané humain|microbiote cutané humain]]<ref>H. Lax et al., ''Longitudinal analysis of microbial interactions between humans and the indoor environment'', Science, 2014.</ref> ;
* une dynamique influencée par les comportements humains (fréquentation des pièces, ventilation, type et fréquence de nettoyage) ; par exemple, Kembel et al. ont montré en 2012 que les pièces ventilées mécaniquement abritent des communautés bactériennes moins diversifiées, et plus riches en microbes associés à l’humain — parfois proches de pathogènes — tandis que les pièces ventilées par l'ouverture de portes ou fenêtres présentent une composition intermédiaire entre l’extérieur et les espaces mécaniquement ventilés. Le design architectural et les conditions intérieures (débit d’air, humidité, température) peuvent donc être utilisés pour orienter la composition du microbiome intérieur, avec des implications directes pour la santé humaine et la gestion des risques dans les environnements bâtis encore à définir.
* une organisation en communautés microbiennes stables mais modulables selon les conditions environnementales (humidité, température, matériaux)<ref>{{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}</ref>.
=== Influence des matériaux et des conditions intérieures ===
Les travaux de la microbiologiste '''Jessica Green''' (Université de l'Oregon) ont montré que les bâtiments fonctionnent comme des écosystèmes particuliers, où les matériaux, la ventilation et l’architecture influencent plus ou moins saisonnièrement la composition microbienne du lieu<ref>Jessica L. Green et al., ''Buildings, microbiomes, and health'', Nature Reviews Microbiology, 2017.</ref>.
Cependant, même dans des environnements très différents, une part importante du microbiote intérieur reste d’origine humaine. Ceci explique les similitudes observées avec le microbiote cutané et respiratoire.
=== Transferts bidirectionnels entre humains et bâtiments ===
Les échanges microbiens entre humains et bâtiments sont '''bidirectionnels''' :
* les occupants déposent des micro-organismes sur les surfaces ;
* les surfaces et l’air intérieur peuvent en retour influencer le microbiote humain, notamment cutané et respiratoire<ref>M. Dannemiller et al., ''Indoor microbial communities: ecology and health effects'', Annual Review of Public Health, 2017.</ref>.
Cette relation réciproque conduit certains chercheurs à considérer les bâtiments comme une « extension écologique » du microbiote humain.
=== Approches récentes et implications ===
Les recherches récentes en '''microbiologie du bâti''' (''building microbiome science'') soulignent l’importance de concevoir des environnements intérieurs favorisant une diversité microbienne bénéfique, dont en utilisant la ventilation naturelle, les matériaux poreux, et par un usage parcimonieux et raisonné des biocides (eau de javel notamment).
Ces travaux s’inscrivent dans une perspective de [[w:santé publique|santé publique]], en lien avec la notion d’'''[[w:exposome|exposome]]''' (qui intègre l’ensemble des expositions environnementales influençant la santé humaine, ou animale pour les animaux domestiques). Néanmoins, on ne sait pas encore définir ce qu’est un environnement intérieur “sain”, ni comment modifier de manière fiable la ventilation, les matériaux ou la conception et l'usage des bâtiments pour influencer positivement ces communautés microbiennes.
Un rapport<ref>{{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}</ref> du NASEM (National Academies of Sciences, Engineering, and Medicine), intitulé ''Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings'', a en 2017, souligné la nécessité d’une [[w:Approche écosystémique|approche écosystémique]] et interdisciplinaire pour comprendre ces interactions complexes et orienter des décisions éclairées en matière d’habitat, d’urbanisme et de santé environnementale.
Beaucoup de microbes (bactéries, virus) ne survivent pas longtemps sur les surfaces sèches, mais malgré cette biomasse réduite, le microbiome intérieur influence grandement la santé humaine, et en particulier l'immunité, le risque de maladies infectieuses et potentiellement les systèmes endocrinien et neurologique. Ce sujet devient crucial à mesure que l’urbanisation augmente. Les avancées récentes en microbiome montrent la nécessité de concevoir des espaces bâtis favorisant un microbiome intérieur bénéfique. xxx ont proposé des stratégies pour cela<ref>Gilbert, J.A., Hartmann, E.M. The indoors microbiome and human health. Nat Rev Microbiol 22, 742–755 (2024). https://doi.org/10.1038/s41579-024-01077-3 |https://www.nature.com/articles/s41579-024-01077-3</ref>.
== Bibliographie ==
* {{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}
* {{Article |prénom1=Simon |nom1=Lax |prénom2=Daniel P. |nom2=Smith |prénom3=Jarrad |nom3=Hampton-Marcell |prénom4=Sarah M. |nom4=Owens |titre=Longitudinal analysis of microbial interaction between humans and the indoor environment |périodique=science.org (Atypon) |volume=345 |numéro=6200 |pages=1048–1052 |date=2014-08-29 |pmid=25170151 |pmcid=4337996 |doi=10.1126/science.1254529 |lire en ligne=https://www.science.org/doi/abs/10.1126/science.1254529 |consulté le=2026-04-21}}
* {{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}
== Références ==
6wx498v2pkn1vncjup09ymywhu5j354
764248
764247
2026-04-21T16:37:53Z
Lamiot
1916
/* Origine humaine majoritaire des micro-organismes intérieurs */ complément
764248
wikitext
text/x-wiki
Des études récentes ont montré qu'il existe des liens forts entre le microbiote humain (microbiote cutané notamment) et l'équivalent d'un « microbiote du bâtiment » ; L'habitat semble fonctionner comme un ''écosystème microbien partagé'', où les occupants humains influencent fortement les communautés microbiennes intérieures et inversement. Ceci n'est pas vraiment surprenant étant donné que les humains passent près de 90 % de leur vie dans des environnements bâtis.
Ces interactions soulèvent des enjeux jusqu'alors ignorés, mais peut être majeurs pour l’urbanisme sain (encore à définir ou redéfinir car les approches hyper-hygiénistes s'avèrent contre-productives voire dangereuses) et pour la conception des bâtiments et des villes, qui doivent favoriser des environnements intérieurs sains, ventilés mais non stériles, favorables à une biodiversité microbienne bénéfique et, tant que possible, défavorable aux microbes pathogènes. Dans une perspective ''[[w:fr:One Health|One Health]]'', comprendre ces dynamiques permet d’intégrer la santé humaine, la qualité de l’air intérieur et la soutenabilité des espaces bâtis dans une même approche écologique.
== Similitudes entre le microbiote humain et le microbiote du bâtiment ==
Le '''microbiote du bâtiment''' désigne ici l’ensemble des micro-organismes (bactéries, champignons, virus) présents dans nos environnements intérieurs. Des chercheurs ont récemment montré qu’il présente de fortes analogies avec le '''microbiote humain''', a priori en raison des échanges constants entre les occupants et leur habitat. La présence de chats, chiens, oiseaux, etc peut aussi le moduler.
De même que le bébé humain acquiert l'essentiel de son microbiote de sa mère et de son environnement après la naissance, on constate que les bâtiments neufs acquièrent égalemnet, progressivement, leur microbiote, passant d’une communauté dominée par l’extérieur à une communauté de plus en plus influencée par la présence humaine après la première ocupation du lieu. Une fois le bâtiment occupé, la richesse et la diversité bactérienne diminuent nettement, tandis que les microbes associés à l’humain (dont ''[[w:Escherichia|Escherichia]], [[w:Pseudomonas|Pseudomonas]], [[w:Klebsiella|Klebsiella]]'') deviennent plus abondants, sous l’effet des interventions humaines et de la sélection environnementale intérieure. L’étude montre que des facteurs architecturaux comme la ventilation, le débit d’air, l’humidité et la température influencent fortement cette transition, ouvrant la voie à une gestion du microbiote intérieur par le design et l’exploitation des bâtiments<ref>{{Article |langue=en |prénom1=Gregory R. |nom1=Young |prénom2=Angela |nom2=Sherry |prénom3=Darren L. |nom3=Smith |titre=Built environment microbiomes transition from outdoor to human-associated communities after construction and commissioning |périodique=www.nature.com |volume=13 |numéro=1 |pages=15854 |date=2023-09-22 |issn=2045-2322 |doi=10.1038/s41598-023-42427-0 |lire en ligne=https://www.nature.com/articles/s41598-023-42427-0 |consulté le=2026-04-21}}</ref>.
=== Origine humaine majoritaire des micro-organismes intérieurs ===
Des études pionnières menées aux USA, dont par le biologiste '''Jack A. Gilbert''' dans le cadre du Home Microbiome Project ont montré que la composition microbienne d’un logement reflète rapidement celle de ses occupants<ref>Jack A. Gilbert et al., ''Microbial ecology of the home environment'', Proceedings of the Royal Society B, 2014.</ref>.
Selon ces travaux, la majorité des bactéries retrouvées sur les surfaces intérieures proviennent de la peau, de la bouche ou du système respiratoire humain.
Les environnements intérieurs conservent des signatures chimiques et microbiennes propres à chaque individu, permettant d’identifier qui a touché quels objets et d’inférer certains aspects de mode de vie (alimentation, médicaments, produits d’hygiène). En combinant métabolomique, séquençage microbien et cartographie moléculaire 3D, li est possible de cartographier en 3 dimensions et dans le temps les interactions entre humains et objets, ce qui est de plus en plus utilisé par les enquêtes politique set les sciences forensiques<ref>Kapono, C.A., Morton, J.T., Bouslimani, A. et al. Creating a 3D microbial and chemical snapshot of a human habitat. Sci Rep 8, 3669 (2018). https://doi.org/10.1038/s41598-018-21541-4</ref>.
=== Similarités structurelles entre microbiotes ===
Les deux microbiotes (celui du bâtiment, et celui des habitants) partagent plusieurs caractéristiques :
* une forte proportion de bactéries issues des phyla '''Firmicutes''' et '''Actinobacteria''', typiques du [[w:fr:microbiote cutané humain|microbiote cutané humain]]<ref>H. Lax et al., ''Longitudinal analysis of microbial interactions between humans and the indoor environment'', Science, 2014.</ref> ;
* une dynamique influencée par les comportements humains (fréquentation des pièces, ventilation, type et fréquence de nettoyage) ; par exemple, Kembel et al. ont montré en 2012 que les pièces ventilées mécaniquement abritent des communautés bactériennes moins diversifiées, et plus riches en microbes associés à l’humain — parfois proches de pathogènes — tandis que les pièces ventilées par l'ouverture de portes ou fenêtres présentent une composition intermédiaire entre l’extérieur et les espaces mécaniquement ventilés. Le design architectural et les conditions intérieures (débit d’air, humidité, température) peuvent donc être utilisés pour orienter la composition du microbiome intérieur, avec des implications directes pour la santé humaine et la gestion des risques dans les environnements bâtis encore à définir.
* une organisation en communautés microbiennes stables mais modulables selon les conditions environnementales (humidité, température, matériaux)<ref>{{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}</ref>.
=== Influence des matériaux et des conditions intérieures ===
Les travaux de la microbiologiste '''Jessica Green''' (Université de l'Oregon) ont montré que les bâtiments fonctionnent comme des écosystèmes particuliers, où les matériaux, la ventilation et l’architecture influencent plus ou moins saisonnièrement la composition microbienne du lieu<ref>Jessica L. Green et al., ''Buildings, microbiomes, and health'', Nature Reviews Microbiology, 2017.</ref>.
Cependant, même dans des environnements très différents, une part importante du microbiote intérieur reste d’origine humaine. Ceci explique les similitudes observées avec le microbiote cutané et respiratoire.
=== Transferts bidirectionnels entre humains et bâtiments ===
Les échanges microbiens entre humains et bâtiments sont '''bidirectionnels''' :
* les occupants déposent des micro-organismes sur les surfaces ;
* les surfaces et l’air intérieur peuvent en retour influencer le microbiote humain, notamment cutané et respiratoire<ref>M. Dannemiller et al., ''Indoor microbial communities: ecology and health effects'', Annual Review of Public Health, 2017.</ref>.
Cette relation réciproque conduit certains chercheurs à considérer les bâtiments comme une « extension écologique » du microbiote humain.
=== Approches récentes et implications ===
Les recherches récentes en '''microbiologie du bâti''' (''building microbiome science'') soulignent l’importance de concevoir des environnements intérieurs favorisant une diversité microbienne bénéfique, dont en utilisant la ventilation naturelle, les matériaux poreux, et par un usage parcimonieux et raisonné des biocides (eau de javel notamment).
Ces travaux s’inscrivent dans une perspective de [[w:santé publique|santé publique]], en lien avec la notion d’'''[[w:exposome|exposome]]''' (qui intègre l’ensemble des expositions environnementales influençant la santé humaine, ou animale pour les animaux domestiques). Néanmoins, on ne sait pas encore définir ce qu’est un environnement intérieur “sain”, ni comment modifier de manière fiable la ventilation, les matériaux ou la conception et l'usage des bâtiments pour influencer positivement ces communautés microbiennes.
Un rapport<ref>{{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}</ref> du NASEM (National Academies of Sciences, Engineering, and Medicine), intitulé ''Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings'', a en 2017, souligné la nécessité d’une [[w:Approche écosystémique|approche écosystémique]] et interdisciplinaire pour comprendre ces interactions complexes et orienter des décisions éclairées en matière d’habitat, d’urbanisme et de santé environnementale.
Beaucoup de microbes (bactéries, virus) ne survivent pas longtemps sur les surfaces sèches, mais malgré cette biomasse réduite, le microbiome intérieur influence grandement la santé humaine, et en particulier l'immunité, le risque de maladies infectieuses et potentiellement les systèmes endocrinien et neurologique. Ce sujet devient crucial à mesure que l’urbanisation augmente. Les avancées récentes en microbiome montrent la nécessité de concevoir des espaces bâtis favorisant un microbiome intérieur bénéfique. xxx ont proposé des stratégies pour cela<ref>Gilbert, J.A., Hartmann, E.M. The indoors microbiome and human health. Nat Rev Microbiol 22, 742–755 (2024). https://doi.org/10.1038/s41579-024-01077-3 |https://www.nature.com/articles/s41579-024-01077-3</ref>.
== Bibliographie ==
* {{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}
* {{Article |prénom1=Simon |nom1=Lax |prénom2=Daniel P. |nom2=Smith |prénom3=Jarrad |nom3=Hampton-Marcell |prénom4=Sarah M. |nom4=Owens |titre=Longitudinal analysis of microbial interaction between humans and the indoor environment |périodique=science.org (Atypon) |volume=345 |numéro=6200 |pages=1048–1052 |date=2014-08-29 |pmid=25170151 |pmcid=4337996 |doi=10.1126/science.1254529 |lire en ligne=https://www.science.org/doi/abs/10.1126/science.1254529 |consulté le=2026-04-21}}
* {{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}
== Références ==
cj7tfhgwvsl4565rfxpqic36o6li7tr
764249
764248
2026-04-21T16:46:23Z
Lamiot
1916
/* Approches récentes et implications */ complément sourcé (virus
764249
wikitext
text/x-wiki
Des études récentes ont montré qu'il existe des liens forts entre le microbiote humain (microbiote cutané notamment) et l'équivalent d'un « microbiote du bâtiment » ; L'habitat semble fonctionner comme un ''écosystème microbien partagé'', où les occupants humains influencent fortement les communautés microbiennes intérieures et inversement. Ceci n'est pas vraiment surprenant étant donné que les humains passent près de 90 % de leur vie dans des environnements bâtis.
Ces interactions soulèvent des enjeux jusqu'alors ignorés, mais peut être majeurs pour l’urbanisme sain (encore à définir ou redéfinir car les approches hyper-hygiénistes s'avèrent contre-productives voire dangereuses) et pour la conception des bâtiments et des villes, qui doivent favoriser des environnements intérieurs sains, ventilés mais non stériles, favorables à une biodiversité microbienne bénéfique et, tant que possible, défavorable aux microbes pathogènes. Dans une perspective ''[[w:fr:One Health|One Health]]'', comprendre ces dynamiques permet d’intégrer la santé humaine, la qualité de l’air intérieur et la soutenabilité des espaces bâtis dans une même approche écologique.
== Similitudes entre le microbiote humain et le microbiote du bâtiment ==
Le '''microbiote du bâtiment''' désigne ici l’ensemble des micro-organismes (bactéries, champignons, virus) présents dans nos environnements intérieurs. Des chercheurs ont récemment montré qu’il présente de fortes analogies avec le '''microbiote humain''', a priori en raison des échanges constants entre les occupants et leur habitat. La présence de chats, chiens, oiseaux, etc peut aussi le moduler.
De même que le bébé humain acquiert l'essentiel de son microbiote de sa mère et de son environnement après la naissance, on constate que les bâtiments neufs acquièrent égalemnet, progressivement, leur microbiote, passant d’une communauté dominée par l’extérieur à une communauté de plus en plus influencée par la présence humaine après la première ocupation du lieu. Une fois le bâtiment occupé, la richesse et la diversité bactérienne diminuent nettement, tandis que les microbes associés à l’humain (dont ''[[w:Escherichia|Escherichia]], [[w:Pseudomonas|Pseudomonas]], [[w:Klebsiella|Klebsiella]]'') deviennent plus abondants, sous l’effet des interventions humaines et de la sélection environnementale intérieure. L’étude montre que des facteurs architecturaux comme la ventilation, le débit d’air, l’humidité et la température influencent fortement cette transition, ouvrant la voie à une gestion du microbiote intérieur par le design et l’exploitation des bâtiments<ref>{{Article |langue=en |prénom1=Gregory R. |nom1=Young |prénom2=Angela |nom2=Sherry |prénom3=Darren L. |nom3=Smith |titre=Built environment microbiomes transition from outdoor to human-associated communities after construction and commissioning |périodique=www.nature.com |volume=13 |numéro=1 |pages=15854 |date=2023-09-22 |issn=2045-2322 |doi=10.1038/s41598-023-42427-0 |lire en ligne=https://www.nature.com/articles/s41598-023-42427-0 |consulté le=2026-04-21}}</ref>.
=== Origine humaine majoritaire des micro-organismes intérieurs ===
Des études pionnières menées aux USA, dont par le biologiste '''Jack A. Gilbert''' dans le cadre du Home Microbiome Project ont montré que la composition microbienne d’un logement reflète rapidement celle de ses occupants<ref>Jack A. Gilbert et al., ''Microbial ecology of the home environment'', Proceedings of the Royal Society B, 2014.</ref>.
Selon ces travaux, la majorité des bactéries retrouvées sur les surfaces intérieures proviennent de la peau, de la bouche ou du système respiratoire humain.
Les environnements intérieurs conservent des signatures chimiques et microbiennes propres à chaque individu, permettant d’identifier qui a touché quels objets et d’inférer certains aspects de mode de vie (alimentation, médicaments, produits d’hygiène). En combinant métabolomique, séquençage microbien et cartographie moléculaire 3D, li est possible de cartographier en 3 dimensions et dans le temps les interactions entre humains et objets, ce qui est de plus en plus utilisé par les enquêtes politique set les sciences forensiques<ref>Kapono, C.A., Morton, J.T., Bouslimani, A. et al. Creating a 3D microbial and chemical snapshot of a human habitat. Sci Rep 8, 3669 (2018). https://doi.org/10.1038/s41598-018-21541-4</ref>.
=== Similarités structurelles entre microbiotes ===
Les deux microbiotes (celui du bâtiment, et celui des habitants) partagent plusieurs caractéristiques :
* une forte proportion de bactéries issues des phyla '''Firmicutes''' et '''Actinobacteria''', typiques du [[w:fr:microbiote cutané humain|microbiote cutané humain]]<ref>H. Lax et al., ''Longitudinal analysis of microbial interactions between humans and the indoor environment'', Science, 2014.</ref> ;
* une dynamique influencée par les comportements humains (fréquentation des pièces, ventilation, type et fréquence de nettoyage) ; par exemple, Kembel et al. ont montré en 2012 que les pièces ventilées mécaniquement abritent des communautés bactériennes moins diversifiées, et plus riches en microbes associés à l’humain — parfois proches de pathogènes — tandis que les pièces ventilées par l'ouverture de portes ou fenêtres présentent une composition intermédiaire entre l’extérieur et les espaces mécaniquement ventilés. Le design architectural et les conditions intérieures (débit d’air, humidité, température) peuvent donc être utilisés pour orienter la composition du microbiome intérieur, avec des implications directes pour la santé humaine et la gestion des risques dans les environnements bâtis encore à définir.
* une organisation en communautés microbiennes stables mais modulables selon les conditions environnementales (humidité, température, matériaux)<ref>{{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}</ref>.
=== Influence des matériaux et des conditions intérieures ===
Les travaux de la microbiologiste '''Jessica Green''' (Université de l'Oregon) ont montré que les bâtiments fonctionnent comme des écosystèmes particuliers, où les matériaux, la ventilation et l’architecture influencent plus ou moins saisonnièrement la composition microbienne du lieu<ref>Jessica L. Green et al., ''Buildings, microbiomes, and health'', Nature Reviews Microbiology, 2017.</ref>.
Cependant, même dans des environnements très différents, une part importante du microbiote intérieur reste d’origine humaine. Ceci explique les similitudes observées avec le microbiote cutané et respiratoire.
=== Transferts bidirectionnels entre humains et bâtiments ===
Les échanges microbiens entre humains et bâtiments sont '''bidirectionnels''' :
* les occupants déposent des micro-organismes sur les surfaces ;
* les surfaces et l’air intérieur peuvent en retour influencer le microbiote humain, notamment cutané et respiratoire<ref>M. Dannemiller et al., ''Indoor microbial communities: ecology and health effects'', Annual Review of Public Health, 2017.</ref>.
Cette relation réciproque conduit certains chercheurs à considérer les bâtiments comme une « extension écologique » du microbiote humain.
=== Approches récentes et implications ===
Les recherches récentes en '''microbiologie du bâti''' (''building microbiome science'') soulignent l’importance de concevoir des environnements intérieurs favorisant une diversité microbienne bénéfique, dont en utilisant la ventilation naturelle, les matériaux poreux, et par un usage parcimonieux et raisonné des biocides (eau de javel notamment).
Ces travaux s’inscrivent dans une perspective de [[w:santé publique|santé publique]], en lien avec la notion d’'''[[w:exposome|exposome]]''' (qui intègre l’ensemble des expositions environnementales influençant la santé humaine, ou animale pour les animaux domestiques). Néanmoins, on ne sait pas encore définir ce qu’est un environnement intérieur “sain”, ni comment modifier de manière fiable la ventilation, les matériaux ou la conception et l'usage des bâtiments pour influencer positivement ces communautés microbiennes.
Un rapport<ref>{{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}</ref> du NASEM (National Academies of Sciences, Engineering, and Medicine), intitulé ''Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings'', a en 2017, souligné la nécessité d’une [[w:Approche écosystémique|approche écosystémique]] et interdisciplinaire pour comprendre ces interactions complexes et orienter des décisions éclairées en matière d’habitat, d’urbanisme et de santé environnementale.
Beaucoup de microbes (bactéries, virus) ne survivent pas longtemps sur les surfaces sèches, mais malgré cette biomasse réduite, le microbiome intérieur influence grandement la santé humaine, et en particulier l'immunité, le risque de maladies infectieuses et potentiellement les systèmes endocrinien et neurologique. Ce sujet devient crucial à mesure que l’urbanisation augmente. Les avancées récentes en microbiome montrent la nécessité de concevoir des espaces bâtis favorisant un microbiome intérieur bénéfique. xxx ont proposé des stratégies pour cela<ref>Gilbert, J.A., Hartmann, E.M. The indoors microbiome and human health. Nat Rev Microbiol 22, 742–755 (2024). https://doi.org/10.1038/s41579-024-01077-3 |https://www.nature.com/articles/s41579-024-01077-3</ref>. <br> Concernant les virus, on a constaté que les environnements bâtis abritent des communautés virales très dépendantes du type d’espace et de son niveau d’occupation, avec une forte présence de virus de la classe ''Caudoviricetes'' sur les surfaces. Les viromes intérieurs montrent des gènes de résistance antimicrobienne et des indices d'interactions étroites avec leurs hôtes bactériens, incluant des systèmes CRISPR/Cas et anti‑CRISPR, qui montrent une dynamique active de coévolution. L’étude montre que les virus sont des acteurs essentiels du microbiome intérieur, influencés par les usages humains et capables d’aider leurs hôtes bactériens à s’adapter à des habitats spécifiques<ref>Du, S., Tong, X., Lai, A.C.K. et al. Highly host-linked viromes in the built environment possess habitat-dependent diversity and functions for potential virus-host coevolution. Nat Commun 14, 2676 (2023). https://doi.org/10.1038/s41467-023-38400-0</ref>.
== Bibliographie ==
* {{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}
* {{Article |prénom1=Simon |nom1=Lax |prénom2=Daniel P. |nom2=Smith |prénom3=Jarrad |nom3=Hampton-Marcell |prénom4=Sarah M. |nom4=Owens |titre=Longitudinal analysis of microbial interaction between humans and the indoor environment |périodique=science.org (Atypon) |volume=345 |numéro=6200 |pages=1048–1052 |date=2014-08-29 |pmid=25170151 |pmcid=4337996 |doi=10.1126/science.1254529 |lire en ligne=https://www.science.org/doi/abs/10.1126/science.1254529 |consulté le=2026-04-21}}
* {{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}
== Références ==
hh524r4szotje86f8x84a12eop9vos8
764252
764249
2026-04-21T16:57:30Z
Lamiot
1916
/* Influence des matériaux et des conditions intérieures */ compl (ex crèche
764252
wikitext
text/x-wiki
Des études récentes ont montré qu'il existe des liens forts entre le microbiote humain (microbiote cutané notamment) et l'équivalent d'un « microbiote du bâtiment » ; L'habitat semble fonctionner comme un ''écosystème microbien partagé'', où les occupants humains influencent fortement les communautés microbiennes intérieures et inversement. Ceci n'est pas vraiment surprenant étant donné que les humains passent près de 90 % de leur vie dans des environnements bâtis.
Ces interactions soulèvent des enjeux jusqu'alors ignorés, mais peut être majeurs pour l’urbanisme sain (encore à définir ou redéfinir car les approches hyper-hygiénistes s'avèrent contre-productives voire dangereuses) et pour la conception des bâtiments et des villes, qui doivent favoriser des environnements intérieurs sains, ventilés mais non stériles, favorables à une biodiversité microbienne bénéfique et, tant que possible, défavorable aux microbes pathogènes. Dans une perspective ''[[w:fr:One Health|One Health]]'', comprendre ces dynamiques permet d’intégrer la santé humaine, la qualité de l’air intérieur et la soutenabilité des espaces bâtis dans une même approche écologique.
== Similitudes entre le microbiote humain et le microbiote du bâtiment ==
Le '''microbiote du bâtiment''' désigne ici l’ensemble des micro-organismes (bactéries, champignons, virus) présents dans nos environnements intérieurs. Des chercheurs ont récemment montré qu’il présente de fortes analogies avec le '''microbiote humain''', a priori en raison des échanges constants entre les occupants et leur habitat. La présence de chats, chiens, oiseaux, etc peut aussi le moduler.
De même que le bébé humain acquiert l'essentiel de son microbiote de sa mère et de son environnement après la naissance, on constate que les bâtiments neufs acquièrent égalemnet, progressivement, leur microbiote, passant d’une communauté dominée par l’extérieur à une communauté de plus en plus influencée par la présence humaine après la première ocupation du lieu. Une fois le bâtiment occupé, la richesse et la diversité bactérienne diminuent nettement, tandis que les microbes associés à l’humain (dont ''[[w:Escherichia|Escherichia]], [[w:Pseudomonas|Pseudomonas]], [[w:Klebsiella|Klebsiella]]'') deviennent plus abondants, sous l’effet des interventions humaines et de la sélection environnementale intérieure. L’étude montre que des facteurs architecturaux comme la ventilation, le débit d’air, l’humidité et la température influencent fortement cette transition, ouvrant la voie à une gestion du microbiote intérieur par le design et l’exploitation des bâtiments<ref>{{Article |langue=en |prénom1=Gregory R. |nom1=Young |prénom2=Angela |nom2=Sherry |prénom3=Darren L. |nom3=Smith |titre=Built environment microbiomes transition from outdoor to human-associated communities after construction and commissioning |périodique=www.nature.com |volume=13 |numéro=1 |pages=15854 |date=2023-09-22 |issn=2045-2322 |doi=10.1038/s41598-023-42427-0 |lire en ligne=https://www.nature.com/articles/s41598-023-42427-0 |consulté le=2026-04-21}}</ref>.
=== Origine humaine majoritaire des micro-organismes intérieurs ===
Des études pionnières menées aux USA, dont par le biologiste '''Jack A. Gilbert''' dans le cadre du Home Microbiome Project ont montré que la composition microbienne d’un logement reflète rapidement celle de ses occupants<ref>Jack A. Gilbert et al., ''Microbial ecology of the home environment'', Proceedings of the Royal Society B, 2014.</ref>.
Selon ces travaux, la majorité des bactéries retrouvées sur les surfaces intérieures proviennent de la peau, de la bouche ou du système respiratoire humain.
Les environnements intérieurs conservent des signatures chimiques et microbiennes propres à chaque individu, permettant d’identifier qui a touché quels objets et d’inférer certains aspects de mode de vie (alimentation, médicaments, produits d’hygiène). En combinant métabolomique, séquençage microbien et cartographie moléculaire 3D, li est possible de cartographier en 3 dimensions et dans le temps les interactions entre humains et objets, ce qui est de plus en plus utilisé par les enquêtes politique set les sciences forensiques<ref>Kapono, C.A., Morton, J.T., Bouslimani, A. et al. Creating a 3D microbial and chemical snapshot of a human habitat. Sci Rep 8, 3669 (2018). https://doi.org/10.1038/s41598-018-21541-4</ref>.
=== Similarités structurelles entre microbiotes ===
Les deux microbiotes (celui du bâtiment, et celui des habitants) partagent plusieurs caractéristiques :
* une forte proportion de bactéries issues des phyla '''Firmicutes''' et '''Actinobacteria''', typiques du [[w:fr:microbiote cutané humain|microbiote cutané humain]]<ref>H. Lax et al., ''Longitudinal analysis of microbial interactions between humans and the indoor environment'', Science, 2014.</ref> ;
* une dynamique influencée par les comportements humains (fréquentation des pièces, ventilation, type et fréquence de nettoyage) ; par exemple, Kembel et al. ont montré en 2012 que les pièces ventilées mécaniquement abritent des communautés bactériennes moins diversifiées, et plus riches en microbes associés à l’humain — parfois proches de pathogènes — tandis que les pièces ventilées par l'ouverture de portes ou fenêtres présentent une composition intermédiaire entre l’extérieur et les espaces mécaniquement ventilés. Le design architectural et les conditions intérieures (débit d’air, humidité, température) peuvent donc être utilisés pour orienter la composition du microbiome intérieur, avec des implications directes pour la santé humaine et la gestion des risques dans les environnements bâtis encore à définir.
* une organisation en communautés microbiennes stables mais modulables selon les conditions environnementales (humidité, température, matériaux)<ref>{{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}</ref>.
=== Influence des matériaux et des conditions intérieures ===
Les travaux de la microbiologiste '''Jessica Green''' (Université de l'Oregon) ont montré que les bâtiments fonctionnent comme des écosystèmes particuliers, où les matériaux, la ventilation et l’architecture influencent plus ou moins saisonnièrement la composition microbienne du lieu<ref>Jessica L. Green et al., ''Buildings, microbiomes, and health'', Nature Reviews Microbiology, 2017.</ref> ; par exemple, les virus présents dans l’air d’une crèche montrent une forte saisonnalité, avec une dominance de virus associés à l’humain en hiver, et de virus associés aux plantes en été<ref>Prussin, A.J., Torres, P.J., Shimashita, J. et al. Seasonal dynamics of DNA and RNA viral bioaerosol communities in a daycare center. Microbiome 7, 53 (2019). https://doi.org/10.1186/s40168-019-0672-z</ref>.
Cependant, même dans des environnements très différents, une part importante du microbiote intérieur reste d’origine humaine. Ceci explique les similitudes observées avec le microbiote cutané et respiratoire.
=== Transferts bidirectionnels entre humains et bâtiments ===
Les échanges microbiens entre humains et bâtiments sont '''bidirectionnels''' :
* les occupants déposent des micro-organismes sur les surfaces ;
* les surfaces et l’air intérieur peuvent en retour influencer le microbiote humain, notamment cutané et respiratoire<ref>M. Dannemiller et al., ''Indoor microbial communities: ecology and health effects'', Annual Review of Public Health, 2017.</ref>.
Cette relation réciproque conduit certains chercheurs à considérer les bâtiments comme une « extension écologique » du microbiote humain.
=== Approches récentes et implications ===
Les recherches récentes en '''microbiologie du bâti''' (''building microbiome science'') soulignent l’importance de concevoir des environnements intérieurs favorisant une diversité microbienne bénéfique, dont en utilisant la ventilation naturelle, les matériaux poreux, et par un usage parcimonieux et raisonné des biocides (eau de javel notamment).
Ces travaux s’inscrivent dans une perspective de [[w:santé publique|santé publique]], en lien avec la notion d’'''[[w:exposome|exposome]]''' (qui intègre l’ensemble des expositions environnementales influençant la santé humaine, ou animale pour les animaux domestiques). Néanmoins, on ne sait pas encore définir ce qu’est un environnement intérieur “sain”, ni comment modifier de manière fiable la ventilation, les matériaux ou la conception et l'usage des bâtiments pour influencer positivement ces communautés microbiennes.
Un rapport<ref>{{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}</ref> du NASEM (National Academies of Sciences, Engineering, and Medicine), intitulé ''Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings'', a en 2017, souligné la nécessité d’une [[w:Approche écosystémique|approche écosystémique]] et interdisciplinaire pour comprendre ces interactions complexes et orienter des décisions éclairées en matière d’habitat, d’urbanisme et de santé environnementale.
Beaucoup de microbes (bactéries, virus) ne survivent pas longtemps sur les surfaces sèches, mais malgré cette biomasse réduite, le microbiome intérieur influence grandement la santé humaine, et en particulier l'immunité, le risque de maladies infectieuses et potentiellement les systèmes endocrinien et neurologique. Ce sujet devient crucial à mesure que l’urbanisation augmente. Les avancées récentes en microbiome montrent la nécessité de concevoir des espaces bâtis favorisant un microbiome intérieur bénéfique. xxx ont proposé des stratégies pour cela<ref>Gilbert, J.A., Hartmann, E.M. The indoors microbiome and human health. Nat Rev Microbiol 22, 742–755 (2024). https://doi.org/10.1038/s41579-024-01077-3 |https://www.nature.com/articles/s41579-024-01077-3</ref>. <br> Concernant les virus, on a constaté que les environnements bâtis abritent des communautés virales très dépendantes du type d’espace et de son niveau d’occupation, avec une forte présence de virus de la classe ''Caudoviricetes'' sur les surfaces. Les viromes intérieurs montrent des gènes de résistance antimicrobienne et des indices d'interactions étroites avec leurs hôtes bactériens, incluant des systèmes CRISPR/Cas et anti‑CRISPR, qui montrent une dynamique active de coévolution. L’étude montre que les virus sont des acteurs essentiels du microbiome intérieur, influencés par les usages humains et capables d’aider leurs hôtes bactériens à s’adapter à des habitats spécifiques<ref>Du, S., Tong, X., Lai, A.C.K. et al. Highly host-linked viromes in the built environment possess habitat-dependent diversity and functions for potential virus-host coevolution. Nat Commun 14, 2676 (2023). https://doi.org/10.1038/s41467-023-38400-0</ref>.
== Bibliographie ==
* {{Ouvrage |langue=en |prénom1=National Academies of Sciences, Engineering, and |nom1=Medicine |prénom2=National Academy of |nom2=Engineering |prénom3=Division on Engineering and Physical |nom3=Sciences |prénom4=Health and Medicine |nom4=Division |titre=Microbiomes of the Built Environment: A Research Agenda for Indoor Microbiology, Human Health, and Buildings |éditeur=National Academies Press |date=2017-11-06 |isbn=978-0-309-44980-9 |lire en ligne=https://books.google.fr/books?id=6LA5DwAAQBAJ&printsec=frontcover&hl=fr&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false |consulté le=2026-04-21}}
* {{Article |prénom1=Simon |nom1=Lax |prénom2=Daniel P. |nom2=Smith |prénom3=Jarrad |nom3=Hampton-Marcell |prénom4=Sarah M. |nom4=Owens |titre=Longitudinal analysis of microbial interaction between humans and the indoor environment |périodique=science.org (Atypon) |volume=345 |numéro=6200 |pages=1048–1052 |date=2014-08-29 |pmid=25170151 |pmcid=4337996 |doi=10.1126/science.1254529 |lire en ligne=https://www.science.org/doi/abs/10.1126/science.1254529 |consulté le=2026-04-21}}
* {{Article |langue=en |prénom1=Steven W |nom1=Kembel |prénom2=Evan |nom2=Jones |prénom3=Jeff |nom3=Kline |prénom4=Dale |nom4=Northcutt |titre=Architectural design influences the diversity and structure of the built environment microbiome |périodique=Multidisciplinary Journal of Microbial Ecology|volume=6 |numéro=8 |pages=1469–1479 |date=2012-08-01 |issn=1751-7362 |issn2=1751-7370 |pmid=22278670 |pmcid=3400407 |doi=10.1038/ismej.2011.211 |lire en ligne=https://academic.oup.com/ismej/article/6/8/1469/7587766 |consulté le=2026-04-21}}
== Références ==
bxlnae2xz3tbi6sqtq0lyp5rwmqrc4a
Discussion utilisateur:~2026-23573-30
3
83828
764348
2026-04-22T08:37:57Z
JackPotte
5426
Page créée avec « {{subst:Test 1}}~~~~ »
764348
wikitext
text/x-wiki
{|class="WSerieH" class="plainlinks" id="vandale" align="center" style="width:100%;margin-bottom:2em;border:1px solid #8888aa;border-right-width:2px;border-bottom-width:2px;background-color:#f7f8ff;padding:5px;text-align:justify"
|-
|[[Image:Nuvola apps important.svg|64px|Arrêtez de vandaliser Wikilivres !]]
|Bonjour {{BASEPAGENAME}},
Vous avez découvert combien il est facile de modifier Wikilivres. Votre modification a été '''annulée''' en raison de son caractère non constructif. Merci de ne pas réitérer ce genre de contribution. Visitez la [[Aide:Accueil|page d’aide]] afin d’en apprendre plus ou le [[Wikilivres:bac à sable|bac à sable]] afin de faire des tests.
|}
[[Catégorie:Vandales avertis]][[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 22 avril 2026 à 10:37 (CEST)
q5caqtvzvyvqp3acrpxl5qli0845p7l