Retro-ingénierie d'une carte Z80 : Electronique et temps de latence

Bonjour à tous,

Il y a de nombreux mois, j'ai récupéré une ancienne centrale téléphonique analogique à base de Z80.  Le dernier article partie 7 se penchait sur l'utilisation d'une pile (stack) pour le processeur Z80.

L'article se proposait de réaliser un feu de passage à niveau en faisant clignoter en alternance deux LEDs. Le projet fût mené a bien mais... 

Bien que plus tard j'y ai découvert une erreur de conception (design flaw) que nous allons pouvoir explorer et corriger.

Source: exemples Z80-ASM

Le temps de latence en électronique

C'est en écrivant d'autres programmes en assembleur que j'ai découvert un drôle de phénomène.

Si le programme faisait un traitement intensif alors l'affichage d'une valeur les LED du port RCIO (image ci-dessus) est rapidement perturbé et affiche un état de donnée non attendue!

Après de très... très longues vérification... j'en suis arrivé à me dire que le problème n'était ni dans le programme assembleur, ni dans la logique matérielle.

C'est comme si le matériel était trop lent à se désactiver... et là on parle de latence.
J'ai donc repris les délais d'activation/désactivation de la chaîne de commande du 74LS375.

Propagation du signal

Le 74LS375 qui commande les LEDs doit recevoir une impulsion à LOW.
Si on inspecte la chaîne de commande, a partir du signal _RCIOce et a1 (en bas a droite), la succession des portes AND impose un délai d'activation de 50nS (nanosecondes) et tout autant pour la désactivation.

Si l'on tient compte du 74HC138 (en haut a gauche) servant à sélectionner le port, on atteint un total de 74nS sans compter que le 74LS375 (Buffer des LEDs) à lui aussi besoin de 15nS.

Sur les 500nS que dure un cycle d'horloge à 2MHz nous ne somme pas très loin du 1/5 du cycle d'horloge. Ajoutons à cela l'impédance du circuit (effet capacitif) et le signal pourrait même se prolonger encore un peu dans le temps.

Cette latence est suffisante pour rencontrer des comportements indésirés.

Correctif #1

Elément à corriger

Pour commencer, il y a deux inverseurs sur les entrées /E2 et E3.
En permutant les entrées /E2 et E3 nous pouvons enlever les deux inverseurs 74LS04. Cela fait déjà 10nS de gagné.

Correctif #2

Réduire la chaîne des portes NAND... malheureusement je n'ai pas de port NAND à 4 entrés! Mais il y a d'autres possibilités  :-)

Elément à corriger

Le graphique du correctif #1 reprend une porte logique OR réalisée avec des diodes (a5 OR a6 OR a7)

Il se fait qu'il est également possible de réaliser une opération logique AND avec des diodes.

Source: inconnue

Le signal Cp est obtenu à l'aide de la formule où un "/" indique un not()

not( _RCIOce * /a1 * a0 * /_wr ) 

que l'on peut réécrire

not( _RCIOce * a0 * /a1 * /_wr )

A noter que /a1 * /_wr peut aussi être réécrit not( a1 + _wr )

Le signal Cp peut s'écrire

not( _RCIOce * a0 * not( a1 + _wr ) )

Les opérations AND (*) ainsi que les opérations OR (+) peuvent être réalisées à l'aide de diodes et il ne reste que les fonction not() qui imposeront un délai de propagation.

Réduction du temps de latence de 50nS à 20+ns

Conclusion

Réduire le nombre de portes semble avoir résolu mon problème d'inconsistance... du moins dans une certaine mesure.

Pour autant que le code soit monolithique il n'y a pas de problème!

Par contre dès que je fais un CALL avec quelques PUSH et POP la carte RCIO recommence à agir bizarrement.

Je vais essayer de réaliser une carte RCIO2 à base d'un module PIO.

Une nouvelle version de la carte CPU-BOARD-ADDON apparaîtra bientôt dans le dépôt du projet.

Aucun commentaire