Comment concevoir efficacement l'opcode pour un CPU?

12

Je construis un simple processeur 16 bits dans Logisim et ai l'ALU prêt et les opcodes que je veux avoir. Maintenant, je trouve vraiment difficile de trouver le bon codage pour les commandes afin que les différents sous-circuits (par exemple, logique, arithmétique) n'aient pas besoin de tous les fils de commande (qui construisent le codage) en entrée, mais aussi peu que possible. Existe-t-il des stratégies ou des méthodes qui aident à concevoir un opcode efficace?

merci d'avance

Benjoyo
la source
1
Construisez d'abord votre ALU et voyez de quels câbles de commande elle a besoin. Câblez-les ensuite directement au registre "instruction courante". Idem pour la logique de contrôle d'accès à la mémoire et toutes les autres grandes classes d'opcodes. Utilisez ensuite les bits restants pour sélectionner le sous-circuit à activer.
user253751
1
Il y a aussi le papier original de Ken Chapman de sa statemachine programmable 8 bits KCPSM alias PicoBlaze. Il décrit comment il a choisi les instructions et conçu l'ISA. dc.uba.ar/materias/disfpga/2010/c2/descargas/…
Paebbels

Réponses:

9

Je pense que c'est une bonne approche pour étudier d'autres ensembles d'instructions.

Un petit serait le MSP430 de TI, c'est un processeur 16 bits avec environ 22 instructions.

http://www.physics.mcmaster.ca/phys3b06/MSP430/MSP430_Instruction_Set_Summary.pdf

Vous pouvez également consulter les AVR Atmel, ils ont également un ensemble d'instructions assez petit.

Dans un petit projet, j'ai essayé de développer un simple processeur 32 bits en VHDL avec un petit jeu d'instructions (14 instructions):

http://www.blog-tm.de/?p=80

En raison de mon temps libre actuel, il n'est pas entièrement terminé. Les instructions sont mises en œuvre mais deux ne sont pas testées et peut-être que certains indicateurs d'état sont manquants.

TM90
la source
Mais je n'ai pas trouvé quelque chose où je pouvais voir quel était l'encodage réel et pourquoi il avait été choisi comme ça.
Benjoyo
Vous pouvez trouver l'encodage actuall dans le repo: github.com/TM90/MISC_Processor/raw/master/Documentation/… . La raison pour laquelle j'ai choisi ces encodages de manière à ce que la logique du décodeur d'instructions soit minimale.
TM90
7

Étudiez (mais ne reproduisez pas) l'approche ARM du codage des instructions. Il est fortement orienté préfixe (comme l'approche de l'arbre de Huffman recommandé par Dzarda) et très uniforme en termes de position du registre de sélection de l'instruction.

L'approche peu imaginative mais fiable consiste à énumérer tous les signaux de contrôle que vous avez, qui seront probablement supérieurs à 16 bits, puis à essayer de faire une minimisation logique de style Karnaugh-map sur eux.

pjc50
la source
Je ne comprends pas vraiment ce que vous entendez par signaux de contrôle.
Benjoyo
Ce que j'ai trouvé et aimé dans l'ARM est le champ de condition, je vais l'inclure.
Benjoyo
Les signaux de contrôle sont les entrées des différents multiplexeurs et permettent de diriger ces données entre les parties de la CPU.
pjc50
Pour une architecture 16 bits, je ne pense pas que le codage d'instructions d'ARM soit approprié. Mayby thumb2 est meilleur. Mais j'aime la méthode d'encodage MIPS, simple et facile à comprendre, bien qu'un peu inutile
phuclv
4

Une fois, j'ai essayé de faire un processeur 4 bits avec un noyau de longueur d'instruction 8 bits dans Logisim. Je me suis retrouvé avec une simple machine à états, plus qu'un CPU, vraiment.

Choses aléatoires à rechercher

  • Arbres Huffman
  • Encodage de longueur fixe ou variable?
  • S'agit-il d'une conception de von Neumann avec un espace d'adressage unique, ou de style Harvard avec des données / programmes séparés?

Excellente vidéo sur Computerphile sur les arbres Huffman:

https://www.youtube.com/watch?v=umTbivyJoiI

Dzarda
la source
Le codage Huffman ne fonctionnera pas pour un codage de longueur fixe, non?
Benjoyo
@Benjoyo Je peux imaginer un scénario avec les bits de rechange utilisés pour des variations des instructions les plus utilisées, offrant ainsi plus de fonctionnalités.
Dzarda
Mais je ne sais pas quel genre d'optimisation cela apporte. Cela ne m'aide pas avec la conception du circuit. Quel est l'objectif lors de l'utilisation du codage Huffman pour l'opcode?
Benjoyo
4

L'ISA que j'ai écrit pour la classe avait un code op 4 bits comme ceci: 1XXX ALU instructions 01XX jump, jump register, call etc 001X branch not equal, branch equal zero 000X 0 - load, 1 - store

Plutôt que d'être le plus optimal, c'est l'un des styles les plus faciles à construire / concevoir des portes car le signal d'entrée d'un seul bit peut contrôler entièrement le chemin logique pris. Alternativement, vous pouvez Huffman Code vos symboles les plus utilisés et les mettre à zéro pour obtenir un code op de longueur fixe.


la source
Ce type d'optimisation est ce que je recherche en ce moment. Mais j'ai un opcode 5 bits et j'ai du mal à regrouper les commandes afin que cela ait du sens dans le circuit.
Benjoyo
@Benjoyo, vous pourriez avoir un tas plus d'instructions ALU avec le bit supérieur. De plus, ma couverture des conditions de saut était assez faible et la plupart des branches normales nécessiteraient deux instructions. En général, je considérais les catégories comme: Math / Contrôle / Mémoire
3

Une chose que vous devrez considérer est d'autoriser ou non toute forme d'instruction multi-mots, ou tout ce qui peut "agir" comme une instruction multi-mots; si vous le faites, vous pouvez alors envisager d'utiliser des mots d'instructions supplémentaires après l'instruction principale ou des mots préfixés avant celle-ci. Autoriser les préfixes et les mots suivants peut augmenter la complexité de la gestion des interruptions, mais cela peut éviter d'avoir à insérer des instructions rarement utilisées dans le même espace d'opcode que celles couramment utilisées.

Si des instructions sont récupérées sur le cycle avant leur exécution, on pourrait avoir une instruction de "branchement conditionnel" qui soit saute le mot d'instruction suivant, soit transfère son contenu directement dans le compteur de programme; une telle conception pourrait ajouter une complexité supplémentaire pour interrompre le séquençage, mais elle pourrait réduire la nécessité d'utiliser une grande partie de l'espace opcode pour les instructions de "branchement", "saut" et "appel", tout en permettant une gamme beaucoup plus large de conditions de branchement que ce ne serait autrement possible. Étant donné qu'une branche qui est prise nécessitera généralement un cycle mort après l'exécution de l'instruction elle-même, quelle que soit l'origine de l'adresse, le fait que l'adresse provienne du mot suivant qui a été récupéré mais ne sera pas exécuté ne coûte rien de plus temps.

Même si le déplacement de l'adresse cible hors des instructions de branche réduira la quantité d'espace d'opcode qu'ils engloutiront, un format d'opcode 16 bits est toujours assez serré. L'utilisation d'instructions de préfixe peut vous aider. Si, par exemple, on veut avoir 32 registres, permettant à n'importe quel registre d'être spécifié indépendamment comme source1, source2 et destination nécessiterait 15 bits dans l'opcode, permettant un total énorme de deux instructions. Pas très utile. D'un autre côté, pouvoir utiliser n'importe lequel des 32 registres pour chacun des trois opérandes serait bien. On pourrait équilibrer les deux objectifs en ayant une opération ALU qui n'est pas précédée d'un préfixe utiliser huit bits pour effectuer deux sélections de registre parmi seize, mais avoir une opération ALU qui suit immédiatement un préfixe, utiliser quelques bits dans le préfixe le long avec huit de l'instruction suivante, afin de permettre une sélection indépendante des deux sources et de la destination à partir de l'ensemble complet de 32. Les instructions qui utilisent les registres supérieurs prendraient deux mots / cycles plutôt qu'un, mais dans certains cas, un tel compromis pourrait être bien utile. La plus grande difficulté avec l'utilisation des préfixes est que l'on doit soit empêcher une interruption de se produire entre un préfixe et l'instruction suivante ou bien s'assurer que si une interruption se produit là, l'instruction après le préfixe utilisera toujours les bons registres [par exemple en ayant le programme - la logique de sauvegarde du compteur stocke l'adresse de la dernière instruction non-préfixe exécutée]. mais dans certains cas, un tel compromis pourrait valoir la peine. La plus grande difficulté avec l'utilisation des préfixes est que l'on doit soit empêcher une interruption de se produire entre un préfixe et l'instruction suivante ou bien s'assurer que si une interruption se produit là, l'instruction après le préfixe utilisera toujours les bons registres [par exemple en ayant le programme - la logique de sauvegarde du compteur stocke l'adresse de la dernière instruction non-préfixe exécutée]. mais dans certains cas, un tel compromis pourrait valoir la peine. La plus grande difficulté avec l'utilisation des préfixes est que l'on doit soit empêcher une interruption de se produire entre un préfixe et l'instruction suivante ou bien s'assurer que si une interruption se produit là, l'instruction après le préfixe utilisera toujours les bons registres [par exemple en ayant le programme - la logique de sauvegarde du compteur stocke l'adresse de la dernière instruction non-préfixe exécutée].

L'utilisation d'instructions en plusieurs mots rendra certains aspects de la conception plus difficiles, mais cela peut réduire la nécessité de prendre d'autres décisions difficiles.

supercat
la source
0

Ce gars a les meilleurs détails pour comprendre le câblage dur de la partie codée en dur d'un décodeur, ce qui explique les lignes de contrôle pour un processeur codé en dur: http://minnie.tuhs.org/CompArch/Tutes/week03.html Comme vous pouvez le voir, votre le choix d'Opcodes a un impact réel sur la complexité de la logique de décodage.

cmacdona101
la source