Obtenir le nombre de bits définis dans la logique numérique

9

En tant qu'exercice, j'essaie de concevoir une implémentation du jeu de la vie de Conway dans une logique numérique simple. Je pourrais tout faire en minimisant une fonction à 9 variables, mais j'imagine que ce sera encore assez grand. L'un des éléments fondamentaux de l'algorithme consiste à déterminer combien de vos 8 voisins sont «vivants».

Étant donné 8 entrées, quelle est la façon la plus simple de déterminer combien sont définies? En particulier, j'ai besoin d'une sortie élevée lorsque 2 sont définies et d'une sortie élevée lorsque 3 sont définies.

Mon idée principale consiste maintenant en un registre à décalage PISO, un compteur et un décodeur 3: 8, mais j'ai à peu près besoin d'un microcontrôleur pour piloter tout cela. Il ne semble pas que cela soit compliqué d'une fonction. Peut-être qu'une ROM 256x2 fonctionnerait également, mais mes recherches n'ont révélé aucun élément de ce type.

Je sais que n'importe quelle image avec 10 IO pourrait le faire trivialement, mais je veux l'implémenter de la manière la plus minimale possible.

captncraig
la source

Réponses:

13

Vous pourriez trouver les différents algorithmes sur l' éclairement rapide du comptage de bits . Les deux derniers: Nifty Parallel Count et MIT HAKMEM Count pourraient bien être faciles à convertir en portes. Voir cette page pour une bonne explication de son fonctionnement.

Vous pouvez le faire en utilisant du matériel Gates. Utilisez quatre additionneurs 1 bit pour ajouter des paires de bits ensemble. Cela vous donne quatre nombres à 3 bits. Ajoutez-les par paires à l'aide de deux additionneurs 3 bits. Cela vous donne deux nombres 4 bits à ajouter à l'aide d'un seul additionneur 4 bits. Cela vous laisse une valeur de 5 bits, mais vous pouvez ignorer le bit supérieur. Utilisez ensuite deux comparateurs 4 bits pour tester les valeurs 2 et 3.

Pour un nombre minimal de pièces, pourquoi ne pas le faire en analogique?

Créez un diviseur de tension avec une résistance en haut et vos 8 entrées connectées en bas par 8 résistances en parallèle. Ensuite, utilisez simplement deux comparateurs pour détecter les niveaux de tension que 2 ou 3 bits vont produire. C'est seulement 6 parties:

Détecteur de nombre de bits

Le réseau à 8 résistances produira une tension entre 0v (pour un jeu de 0 bits) à 5v (pour un jeu de 8 bits). 2 bits produiront 0,5 V. 3 bits produiront 1,56v.

  • Avec 0 ou 1 bits, la sortie sera 00.
  • Avec 2 ou 3 bits, la sortie sera 01.
  • Avec 4 bits ou plus, la sortie sera 11.

Ajoutée:

Merci à DavidCary pour une excellente suggestion. Après beaucoup de calculs, je pense avoir trouvé un ensemble de résistances qui fonctionnent, mais vous devez d'abord vérifier attentivement mes calculs. Ici, j'utilise des comparateurs avec des sorties à drain ouvert et je pense que j'ai réussi à obtenir une seule sortie. Faible signifie mort au prochain tour, élevé signifie vivant au prochain tour.

Circuit de jeu de la vie de Conway 2

La bonne chose est que ce circuit n'a que deux composants de plus que l'autre circuit. Ce sont toutes des résistances de la série E8, il devrait donc être possible de les obtenir. De plus, R6 aurait dû être une valeur plus élevée, comme 4.7k ou quelque chose.

Rocketmagnet
la source
4
+1 simplement parce que votre réponse n'est pas "Utiliser un microcontrôleur". Cela semble être le mode par défaut ici.
Connor Wolf
@FakeName: La première référence concerne les solutions logicielles. Bien sûr, vous n'avez pas à les implémenter sur un microcontrôleur, vous pouvez également utiliser un supercalculateur :)
Federico Russo
@ FedericoRusso - J'ai donné ces références aux solutions logicielles qui donnent un aperçu de la façon dont il pourrait l'implémenter dans le matériel.
Rocketmagnet
3
Peut-être: ajouter une 9e "résistance de sommation" de 20 kOhm de l'état actuel de la cellule centrale au point de sommation "+" de l'ampli-op dans le circuit de Rocketmagnet - c'est-à-dire, donner à la cellule centrale un poids de 1 et les 8 cellules voisines un poids de 2. Puis ajustez le diviseur de tension pour "naissance" (cellule morte centrale avec 3 voisins vivants; somme = 6) et "rester en vie" (cellule morte centrale vivante avec 2 ou 3 voisins vivants, somme = 5 ou 7) donne des sorties de "01"; et tous les autres cas (où la cellule centrale meurt ou reste morte) donnent des sorties de "00" ou "11". Ensuite, une porte XOR donne l'état suivant de la cellule centrale.
davidcary
1
J'ai découvert quelques choses en faisant des expériences: les résistances ne sont pas tout à fait correctes. J'ai trouvé quelques meilleures combinaisons mais j'essaie toujours d'optimiser. De plus, lors de la création d'une grille de ceux-ci, le courant circulera à travers les résistances de sommation et gâchera les choses. Les diodes sur les liens sont un moyen d'éviter cela.
captncraig
6

μ

La table de recherche est également composée d'une seule partie et est plus rapide que le microcontrôleur. Oubliez les EEPROM parallèles, elles sont chères. Utilisez un Flash parallèle sur tout l'octet . Celui-ci fait 512 Ko, c'est 2000 fois plus que ce dont vous avez besoin, mais c'est la solution la moins chère (1 dollar). Et vous pouvez ajouter 6 fonctions 1 bit supplémentaires pour le même prix.

Vous pouvez également utiliser un CPLD . Écrivez la fonction en VHDL ou Verilog comme une longue instruction SOP (Sum Of Products) et laissez le synthétiseur créer la logique.

Le registre à décalage est OK si vous pouvez attendre le résultat; c'est la solution la plus lente.

Enfin, vous pouvez le faire avec des portes logiques , mais vous passerez beaucoup de temps à réduire le SOP à sa forme minimale si vous voulez passer à la base. Rocketmagnet a la bonne idée d'utiliser des additionneurs, mais ses chiffres sont faux: un demi-additionneur 1 bit donne 2 bits, pas 3. Donc, ajouter les sorties des demi-additionneurs deux par deux nécessite deux demi-additionneurs 2 bits, donnant deux 3- résultats peu. Utilisez un demi-additionneur 3 bits pour obtenir le résultat 4 bits. En utilisant des additionneurs complets 1 bit, vous n'aurez besoin que d'un seul additionneur 2 bits.

stevenvh
la source
1

Les circuits hybrides séquentiels parallèles sont susceptibles d'être beaucoup plus compacts que les circuits purement parallèles. Par exemple, si vous ajustez les règles de manière à ce qu'une case 3x3 transforme la cellule au centre mort s'il y a moins de trois cellules vivantes ou plus de quatre, et la rende vivante s'il y a exactement trois cellules vivantes (le comportement sous ces les nouvelles règles correspondront à l'original), on peut simplifier la logique en faisant une séquence en deux étapes:

tempVal [x, y] = orig [x-1, y] + orig [x, y] + orig [x + 1, y] 'Somme à deux bits de trois nombres à un bit
orig [x, y] = LiveDeadFunc (orig [x, y], tempval [x, y-1] + tempVal [x, y] + tempVal [x, y + 1])

Le tableau tempVal[x,y]a deux bits par cellule; cette dernière opération additionne trois de ces nombres pour produire une valeur de 0 à 9 (bien que toutes les valeurs supérieures à quatre soient équivalentes), qui peuvent ensuite être utilisées pour calculer un état vivant / mort sur un seul bit pour la génération suivante.

BTW, une alternative à la réalisation d'une somme arithmétique dans la deuxième étape et à l'examen de la valeur serait de convertir tempVal [x, y] en une représentation à chaud, puis de rechercher explicitement l'une des neuf combinaisons de valeurs qui donneraient trois cellules, ou l'un des douze qui donnerait quatre.

supercat
la source