1M×8 · CS̄ · WĒ · OĒ · Banques · Chronogramme
Un processeur comme le 8086 d'Intel travaille avec des mots de 16 bits. Il veut lire 16 bits d'un seul coup à chaque accès mémoire. Or les puces mémoire disponibles ne proposent souvent que 4 ou 8 bits par adresse.
Il faut donc assembler plusieurs puces pour satisfaire le processeur. Il existe deux types d'assemblage, et on les combine souvent :
Supposons qu'on veuille construire une mémoire de 4 Mo avec des puces 1M × 4 :
— Le processeur lit 8 bits à la fois → il faut 2 puces en largeur (2×4 = 8 bits)
— On veut 4M d'adresses, mais chaque groupe ne couvre que 1M → il faut 4 groupes en profondeur
→ Total : 2 × 4 = 8 puces 1M×4 pour obtenir 4M × 8
On a deux puces 1M × 4. Chacune peut stocker 4 bits par adresse. On veut un système qui stocke 8 bits par adresse. La solution : les mettre côte à côte et partager le bus d'adresse entre les deux.
Règle de câblage :
┌─────────────────────────────────────────────────────────────┐ │ CÂBLAGE 1M×8 depuis 2 × (1M×4) │ └─────────────────────────────────────────────────────────────┘ Broches d'adresse : A0–A19 de la PUCE 1 ←──┬──→ A0–A19 de la PUCE 2 │ (fil commun) ← les deux reçoivent la MÊME adresse Broches de données : PUCE 1 : D0, D1, D2, D3 → bus bits 0 à 3 (octet bas) PUCE 2 : D0, D1, D2, D3 → bus bits 4 à 7 (octet haut) ↑ renommés D4–D7 Signal CS̄ : CS̄ PUCE 1 ─── reliés ensemble ─── CS̄ PUCE 2 (activées et désactivées en même temps)
On place l'adresse 1000 (= 0b00000000001111101000) sur A0–A19.
Les deux puces reçoivent simultanément cette même adresse.
— PUCE 1 va chercher à sa case n°1000, elle trouve : 1 0 1 1 → elle sort ça sur D0–D3
— PUCE 2 va chercher à sa case n°1000, elle trouve : 0 1 1 0 → elle sort ça sur D4–D7
Le résultat sur le bus de données 8 bits est : 0110 1011 = 0x6B
↑ bits 7–4 de la puce 2 ↑ bits 3–0 de la puce 1
Schéma de principe : BUS D'ADRESSE A0–A19 (20 fils, même valeur sur les 2 puces) ┌────────────────────┴────────────────────┐ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ PUCE 1 │ │ PUCE 2 │ │ 1M × 4 │ │ 1M × 4 │ │ │ │ │ │ D0 D1 D2 D3│ │ D0 D1 D2 D3│ └──┬──┬──┬──┬┘ └──┬──┬──┬──┬┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ D0 D1 D2 D3 D4 D5 D6 D7 └───────────────────────────────────────────────────┘ BUS DE DONNÉES — 8 bits — vers le processeur
| Bus d'adresse | Identique — toujours 20 broches, les deux puces reçoivent exactement la même adresse au même moment |
| Bus de données | Doublé — puce 1 donne D0–D3, puce 2 donne D4–D7. Ensemble ils forment 8 bits en parallèle |
| CS̄, WĒ, OĒ | Partagés — les deux puces sont commandées exactement de la même façon |
Imagine que tu as 4 puces mémoire branchées sur le même bus de données. Le processeur envoie une adresse, et il s'attend à ne recevoir qu'une seule réponse. Mais si les 4 puces répondent en même temps sur le même fil, ça donne n'importe quoi — c'est un court-circuit logique.
La broche CS̄ (Chip Select, avec une barre car active à l'état bas) est l'interrupteur général de chaque puce : elle permet de n'activer qu'une seule puce à la fois.
CS̄ = 1 → La puce est MUETTE Elle ne lit pas l'adresse Ses broches de données sont en HAUTE IMPÉDANCE (Z) = elles sont "déconnectées" électriquement du bus = comme si la puce n'existait pas CS̄ = 0 → La puce est ACTIVE Elle lit l'adresse sur A0–A19 Elle peut répondre sur les broches de données
Quand une broche est en haute impédance, elle n'est ni à 0 ni à 1. C'est comme si le fil était coupé. La puce se "déconnecte" physiquement du bus sans avoir besoin de retirer le fil. C'est ce qui permet à plusieurs puces de partager le même fil de données : une seule sort sa réponse, les autres sont en Z et laissent passer.
Chaque puce couvre 256K adresses. Ensemble elles couvrent 4 × 256K = 1M adresses.
Le processeur génère une adresse. Le décodeur d'adresse (un circuit logique simple) regarde les 2 bits de poids fort (A18–A19) et active la bonne puce via son CS̄.
A19 A18 → Quelle puce activer ? 0 0 → PUCE A CS̄=0 (adresses 0x00000 – 0x3FFFF) 0 1 → PUCE B CS̄=0 (adresses 0x40000 – 0x7FFFF) 1 0 → PUCE C CS̄=0 (adresses 0x80000 – 0xBFFFF) 1 1 → PUCE D CS̄=0 (adresses 0xC0000 – 0xFFFFF) À un instant donné, UNE seule puce a CS̄=0. Les 3 autres sont à CS̄=1 (muettes).
Scénario : le processeur veut lire l'adresse 0x50000.
En binaire : A19=0, A18=1, A17–A0 = ... → c'est dans la plage de la PUCE B.
→ Le décodeur met CS̄ de PUCE B = 0, et CS̄ des puces A, C, D = 1.
→ Seule PUCE B répond sur le bus de données. Pas de collision.
Si deux puces ont CS̄=0 au même moment et que l'une veut sortir un 1 et l'autre un 0 sur le même fil de données, il y a conflit électrique. Ça peut endommager les puces et donne une donnée aléatoire. C'est pourquoi le CS̄ est fondamental dans toute architecture mémoire.
Une fois la puce activée (CS̄=0), elle ne sait pas encore ce qu'on veut. Doit-elle sortir une donnée vers le processeur (lecture) ? Ou doit-elle recevoir une donnée depuis le processeur (écriture) ?
C'est le rôle de deux broches de contrôle :
Table de vérité complète — toutes les combinaisons possibles :
| CS̄ | WĒ | OĒ | Mode | Bus données D0–Dn | Ce qui se passe |
|---|---|---|---|---|---|
| 1 | X | X | Puce désactivée | Haute impédance Z | La puce ignore tout |
| 0 | 1 | 0 | ✓ LECTURE | Sortie — données lues | La puce sort les 4/8 bits mémorisés à l'adresse |
| 0 | 0 | 1 | ✎ ÉCRITURE | Entrée — données reçues | La puce enregistre les bits présents sur D0–Dn |
| 0 | 1 | 1 | Stand-by | Haute impédance Z | Puce active mais silencieuse |
| 0 | 0 | 0 | ⚠ INTERDIT | Conflit ! | Lecture ET écriture simultanées → conflit, comportement indéfini |
Le X signifie "peu importe" — quand CS̄=1, WĒ et OĒ n'ont aucun effet.
On veut lire la case n°200 1. A0–A19 = 200 ← on pointe la même case 2. CS̄ = 0 ← on active la puce 3. OĒ = 0 ← on autorise la sortie 4. WĒ = 1 ← on interdit l'écriture Résultat sur D0–D7 : 10100011 = 0xA3 ✓ ← la valeur qu'on avait écrite !
Un chronogramme est un graphique qui montre comment les signaux évoluent dans le temps. C'est crucial car les signaux doivent arriver dans le bon ordre et rester stables assez longtemps pour que la puce les "lise" correctement. Un mauvais timing = données corrompues.
Chronogramme d'un cycle de LECTURE :
─── temps qui passe ───► t0 t1 t2 t3 t4 │ │ │ │ │ ADRESSE XXXXX━━━━━━━━━━━━━━━━━━━━━XXXXX ↑ ↑ ↑ invalide stable change (l'adresse ne bougera plus jusqu'en t4) CS̄ ━━━━━━┓ ┏━━━━━ ┗━━━━━━━━━━━━━━━━━┛ ↑ tombe à 0 ↑ remonte à 1 OĒ ━━━━━━━━━━━┓ ┏━━━━━━━━ ┗━━━━━━━━━┛ ↑ active ↑ fin lecture WĒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (WĒ reste à 1 tout le temps → pas d'écriture) DONNÉES ZZZZZZZZZZZZZZZZ━━━━━━━ZZZZZZZZ haute impédance ↑ donnée valide ↑ Z ←───────────────────────────────► ↑ tACC (temps d'accès de la puce) ↑ (ex: 70 ns pour une SRAM classique)
| t0 → t1 | Le processeur place l'adresse sur A0–A19. Elle se stabilise. On attend qu'elle soit stable avant de tout déclencher. |
| t1 | CS̄ tombe à 0 → la puce se "réveille" et commence à décoder l'adresse en interne. |
| t2 | OĒ tombe à 0 → la puce est autorisée à sortir les données sur le bus. |
| t2 + tACC | Après le temps d'accès (délai interne à la puce, ex: 70 ns), la donnée est valide sur D0–Dn. Le processeur peut la lire. |
| t3 → t4 | OĒ puis CS̄ remontent à 1. Le bus retourne en Z. Fin du cycle. |
Chronogramme d'un cycle d'ÉCRITURE :
t0 t1 t2 t3 t4 │ │ │ │ │ ADRESSE XXXXX━━━━━━━━━━━━━━━━━━━━━XXXXX (stable en t1) DONNÉES XXXXX━━━━━━━━━━━━━━━━━━━━━XXXXX (le processeur met la donnée sur le bus) CS̄ ━━━━━━┓ ┏━━━━━ ┗━━━━━━━━━━━━━━━━━┛ WĒ ━━━━━━━━━━━┓ ┏━━━━━━━━ ┗━━━━━━━━━┛ ↑ ↑ WĒ tombe à 0 WĒ remonte à 1 c'est le front montant de WĒ qui déclenche l'écriture en mémoire ! OĒ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ (OĒ reste à 1 tout le temps → pas de lecture)
En écriture, on active toujours CS̄ en premier, puis WĒ ensuite. Et on remonte WĒ en premier avant de remonter CS̄. Pourquoi ? Car si on activait WĒ avant que l'adresse soit stable, on risque d'écrire par erreur dans une mauvaise case pendant la transition. Cette discipline de séquençage est critique pour éviter la corruption de données.
Les bits A20 et A21 (les deux nouveaux bits de poids fort) servent à sélectionner la bonne puce via le décodeur de CS̄ :
Bus d'adresse : A0–A21 (22 bits = 4 194 304 adresses = 4M) A21 A20 → Puce activée Plage couverte 0 0 → PUCE 0 CS̄=0 adresses 0x000000 – 0x0FFFFF (0 à 1M-1) 0 1 → PUCE 1 CS̄=0 adresses 0x100000 – 0x1FFFFF (1M à 2M-1) 1 0 → PUCE 2 CS̄=0 adresses 0x200000 – 0x2FFFFF (2M à 3M-1) 1 1 → PUCE 3 CS̄=0 adresses 0x300000 – 0x3FFFFF (3M à 4M-1) Les bits A0–A19 vont sur TOUTES les puces (ils sélectionnent la case à l'intérieur) Les bits A20–A21 vont au DÉCODEUR qui génère les CS̄
0x250000 en binaire = 10 0101 0000 0000 0000 0000 0000
→ A21=1, A20=0 → c'est la combinaison "1 0" → PUCE 2 est sélectionnée
→ A0–A19 = 0x50000 = la case 327 680 à l'intérieur de PUCE 2
→ CS̄ de PUCE 2 = 0 (active), CS̄ des puces 0,1,3 = 1 (muettes)
A21=1, A20=0
│
┌─────▼──────┐
│ DÉCODEUR │
│ d'adresse │
└──┬──┬──┬──┬┘
CS̄=1 → Puce 0 ─┘ │ │ └─ CS̄=1 → Puce 3
CS̄=1 → Puce 1 ────┘ └──── CS̄=0 → Puce 2 ← ACTIVE
Pour construire une mémoire N × M à partir de puces n × m :
— Nombre de puces en largeur = M / m (ex: 8/4 = 2 puces pour passer de ×4 à ×8)
— Nombre de puces en profondeur = N / n (ex: 4M/1M = 4 groupes)
— Nombre total de puces = (M/m) × (N/n)
Exemple : construire 4M×8 avec des puces 256K×4 Largeur : 8 / 4 = 2 puces par groupe Profondeur: 4M/256K = 4 194 304 / 262 144 = 16 groupes Total : 2 × 16 = 32 puces 256K×4