Concevoir une ALU simple


8

Je dois concevoir une ALU avec deux entrées A et B 8 bits et contrôler les entrées x, y et z qui prennent en charge les opérations suivantes:

x  y  z  |  operation

0  0  0  |  S = A-B
0  0  1  |  S = A+B
0  1  0  |  S = A*8
0  1  1  |  S = A/8
1  0  0  | S = A NAND B (bitwise)
1  0  1  | S = A XOR B (bitwise)
1  1  0  | s = reverse the bits of A
1  1  1  | S = NOT A (bitwise)

Ceci est censé être fait avec un additionneur 8 bits et un extenseur arithmétique et logique. En lisant mon manuel, je vois que le but d'un extenseur AL est de modifier les bits d'entrée afin qu'un additionneur, plutôt que beaucoup de composants supplémentaires, puisse être utilisé pour tout faire (ou du moins c'est ce que je comprends de lui ). Par exemple, l'extension AL pourrait mettre les bits en complément à deux afin que l'additionneur fasse une soustraction. De même, pour les opérations logiques au niveau du bit, les bits peuvent être modifiés de manière appropriée et l'une des entrées d'additionneur peut simplement être nulle afin que le résultat passe correctement.

Mais que faire exactement de la multiplication? Mon livre est très vague, donc je ne suis pas sûr qu'un extenseur AL m'oblige à faire quelque chose d'intelligent pour que l'additionneur fasse le travail (ajoutez juste 8 fois dans mon cas? ... ha ha), ou si je peut simplement jeter un multiplicateur là-dedans. Je vais devoir lire sur la division, mais je parie que c'est similaire à la multiplication.

Eh bien, de toute façon, le résultat final est toujours, qu'est-ce qu'un extenseur AL "autorisé" à / peut avoir en lui? Son seul but est-il de modifier l'entrée afin qu'elle puisse être envoyée à un additionneur?

* EDIT: Eh bien, c'est une multiplication / division par 8, donc cela peut être facilement effectué avec un décalage vers la gauche ou vers la droite par 3. Aurais-je encore une extension AL réelle / appropriée si j'y ajoutais des sélecteurs? (Peut-être que j'y pense trop en tant que débutant complet ...)


1
Qu'est-ce que 00011111 * 8? Qu'est-ce que 00000000-00000111? Si votre amplificateur AL décale à gauche 3 fois pour le code d'opération "010", il peut alors affecter B à 0, puis invoquer les codes d'opération "001" ou "000" dans l'ALU.
Tony Ennis

Réponses:


5

L'approche la plus simple serait de décoder les entrées xyz en huit lignes. Ensuite, à partir de ceux-ci, vous implémentez une logique qui pilote les lignes de sélection de puce pour activer l'unité appropriée qui gère les entrées, ainsi que toutes les transformations nécessaires pour que l'unité effectue le bon fonctionnement.

Je ne pense pas que vous pouvez utiliser un additionneur pour vos opérations logiques car l'additionneur porte (à moins qu'il ait une entrée qui désactive le comportement de propagation de portage). Mais vous pouvez avoir une seule unité pour faire toute la logique.

Peut-être qu'il y a une raison pour laquelle ils appellent ces ALU, avec un A et un L. :)

La multiplication par 8 signifie simplement conduire des zéros sur les trois lignes d'entrée les plus basses, ignorer les trois lignes supérieures et mapper la ligne 0 à la ligne 3, 1 à 4, etc. C'est comme un aiguillage ferroviaire.


6

(Triche)
La solution la plus simple mais la plus puissante consiste à utiliser une mémoire Flash comme table de recherche pour les résultats. Entrée 8 bits A + entrée 8 bits B + code de fonctionnement à 3 bits: 19 bits. Choisissez un Flash de 512 k 16 bits (environ 2 $), utilisez les 19 lignes d'entrée comme adresse et programmez-le avec les résultats pour chaque combinaison d'entrée. De cette façon, vous pouvez avoir n'importe quelle opération que vous aimez. Tu veux le péché (A)? Ajoutez simplement une table de recherche sinus de 256 mots, vous pouvez même avoir un résultat précis de 16 bits. Vous n'êtes pas limité à multiplier par 8; vous pouvez multiplier A par B. Comme sage, vous pouvez diviser A par B, et obtenir un quotient de 8 bits et×un reste de 8 bits. Pour la multiplication et la division, vous utiliserez tous les bits dans un bloc de 64 mots, mais par exemple, l'inversion des bits en fait un usage moins efficace: cela ne dépend pas de la valeur de B, vous aurez donc 256 valeurs identiques pour chaque entrée A, et l'octet de poids fort ne serait même pas utilisé. Ainsi, alors que vous n'avez besoin que de 256 8 = 2048 bits pour l'inversion de bits, vous utiliserez 65536 16 = 1048576 bits; ce n'est pas très efficace. Vous pourriez appeler cela un sérieux inconvénient de la solution Flash, mais j'aimerais vous voir implémenter un multiplicateur 8 8 en utilisant des portes logiques de base pour 2 $.×××

OK, peut-être que vous ne voulez pas ça; les portes logiques sont beaucoup plus difficiles. Comme Kaz le dit, commencez par un décodeur 3 à 8 pour avoir un signal unique pour chaque opcode. Vous pouvez le faire avec des portes de base, mais je suggère d'utiliser un 74HC238 pour commencer. Lorsque l'ALU fonctionne, vous pouvez toujours remplacer le HC238 par une collection de portes.

Ce que vous ne voulez pas pour le multiplicateur, c'est un registre à décalage qui décale à gauche 3 fois. C'est une fonction enregistrée qui a besoin d'une horloge, au lieu d'une fonction combinatoire qui produit le résultat immédiatement. (Notez que le Flash produit également un résultat en nanosecondes, bien que plus lent qu'avec la logique combinatoire.) Avoir un chemin de A0 à Y3, A1 à Y4, etc., que vous activez avec l'opcode décodé "010". De même, Y3 sera connecté à A6 si le signal "011" est actif (division), et à A4 lorsque l'opcoe est "110" (inversion de bit). Cela signifie beaucoup de multiplexage.

Pour revenir au Flash, vous pouvez également faire une combinaison de logique combinatoire pour des opérations simples, comme NAND, NOR, décalage à gauche, décalage à droite , et n'utiliser le Flash que pour la multiplication et la division. Vous pouvez utiliser un Flash plus petit (128 kword au lieu de 512 kword), ou ajouter des fonctions plus avancées, comme le sinus que j'ai donné en exemple (peut-être pas le meilleur, mais je suis sûr que vous pouvez penser à quelque chose).()



() Comment se fait-il que vous ayez une multiplication par 8, mais pas le décalage le plus basique à gauche? Shift gauche / droite, rotation gauche / droite (à la fois par report et non) sont indispensables pour tout ALU, et vous pouvez diviser par 8 en utilisant 3 droits de décalage, tandis que vous ne pouvez pas diviser par 2. L'inversion de bits est un DSP typique fonction, mais vous ne voulez pas construire un DSP pour commencer, n'est-ce pas? Je changerais les fonctions en

x  y  z  |  operation

0  0  0  |  S = A - B
0  0  1  |  S = A + B
0  1  0  |  S = shift left A by 1 bit
0  1  1  |  S = shift right A by 1 bit
1  0  0  |  S = A NAND B (bitwise)
1  0  1  |  S = A XOR B (bitwise)
1  1  0  |  S = rotate left A
1  1  1  |  S = NOT A (bitwise)

1

Je suis resté coincé sur le même problème dans le même livre. Heureusement, je suis tombé sur ce fil qui m'a donné une idée de ce que je devais faire. Kaz a un très bon point sur la conduite des zéros et la cartographie des lignes. L'extendeur ALU dans ce livre est conçu de n (n représentant le nombre de bits sur lesquels opérer) des composants combinatoires identiques mais séparés et un composant différent pour le transfert. Ces composants ont cinq entrées et deux sorties. Les cinq entrées sont: «X», «Y», «Z» (pour sélectionner l'opération) et «a», «b» (bits individuels de A et B de même signification). Je suppose que l'idée ici est de diviser le problème en plus petits morceaux afin d'avoir une table de vérité de taille raisonnable. Soit 5 entrées vs 8 + 8 + 3 = 19 entrées si le répéteur accepterait tous les bits des entrées A et B plus les commandes. Maintenant, si l'extendeur était composé de cette manière (19 entrées), je pense que la logique de multiplication pourrait être implémentée dans ce composant unique, mais il serait hors de question d'écrire une table de vérité pour cela. Donc, de toute façon, ma solution consiste à utiliser des multiplexeurs après chaque composant qui gère les bits individuels a et b en supposant que le composant est déjà conçu de telle sorte qu'une entrée XYZ = 010 passe «un» bit inchangé et filtre «b», c'est-à-dire 'b' = 0. Le multiplexeur doit avoir deux entrées, une du composant ci-dessus et une du composant trois places à droite. Trois multiplexeurs les plus à droite devraient avoir des zéros comme deuxième entrée. Une logique combinatoire simple avec une porte ET et deux onduleurs peut définir les multiplexeurs lorsque XYZ = 010.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.