Ottieni il numero di bit impostati nella logica digitale


9

Come esercizio, sto cercando di progettare un'implementazione del gioco della vita di Conway in una semplice logica digitale. Potrei fare tutto minimizzando una funzione a 9 variabili, ma immagino che sarà ancora abbastanza grande. Uno degli elementi chiave dell'algoritmo è determinare quanti dei tuoi 8 vicini sono "vivi".

Dati 8 input, qual è il modo più semplice per determinare quanti sono impostati? In particolare ho bisogno di un'uscita alta quando sono impostati 2 e un'uscita alta quando sono impostati 3.

La mia idea principale ora consiste in un registro a scorrimento PISO, un contatore e un decodificatore 3: 8, ma ho praticamente bisogno di un microcontrollore per guidare tutto ciò. Non sembra così complicato di una funzione. Forse funzionerebbe anche una ROM 256x2, ma le mie ricerche non hanno rivelato nessuna di queste parti.

So che qualsiasi foto con 10 IO potrebbe farlo in modo banale, ma voglio implementarlo nel modo più minimale ragionevolmente possibile.

Risposte:


13

Potresti trovare i vari algoritmi sull'illuminante Fast Bit Counting . Gli ultimi due: Nifty Parallel Count e MIT HAKMEM Count potrebbero essere facili da convertire in gate. Vedi questa pagina per una buona spiegazione di come funziona.

Puoi farlo usando l'hardware di Gates. Utilizzare quattro additivi da 1 bit per aggiungere coppie di bit insieme. Questo ti dà quattro numeri a 3 bit. Aggiungili in coppia usando due additivi a 3 bit. Questo ti dà due numeri a 4 bit da aggiungere usando un singolo sommatore a 4 bit. Questo ti lascia con un valore di 5 bit, ma puoi ignorare il bit superiore. Quindi utilizzare due comparatori a 4 bit per verificare i valori 2 e 3.

Per un numero minimo di parti, perché non farlo analogico?

Crea un divisore di tensione con un resistore in alto e gli 8 ingressi collegati in basso da 8 resistori in parallelo. Quindi utilizzare semplicemente due comparatori impostati per rilevare i livelli di tensione che produrranno 2 o 3 bit. Sono solo 6 parti:

Rilevatore di conteggio dei bit

La rete a 8 resistori produrrà una tensione compresa tra 0 v (per set di 0 bit) e 5 v (per set di 8 bit). 2 bit produrranno 0,5 V. 3 bit produrranno 1.56v.

  • Con 0 o 1 bit, l'uscita sarà 00.
  • Con 2 o 3 bit, l'uscita sarà 01.
  • Con 4 o più bit, l'uscita sarà 11.

Inserito il:

Grazie a DavidCary per un suggerimento eccellente. Dopo molti calcoli, penso di aver trovato una serie di resistori che funzionano, ma prima dovresti controllare attentamente i miei calcoli. Qui sto usando comparatori con output open-drain e penso di essere riuscito a farlo avere un singolo output. Basso significa morto il prossimo turno, Alto significa vivo il prossimo turno.

Circuito del gioco della vita di Conway 2

La cosa bella è che questo circuito ha solo due componenti in più rispetto all'altro circuito. Sono tutti resistori serie E8, quindi dovrebbe essere possibile contattarli. Inoltre, R6 avrebbe dovuto avere un valore più alto, come 4.7k o qualcosa del genere.


4
+1 solo perché la tua risposta non è "Usa un microcontrollore". Questa sembra essere la modalità predefinita qui.
Connor Wolf,

@FakeName: il primo riferimento è alle soluzioni software. Ovviamente non devi implementarli su un microcontrollore, puoi anche usare un supercomputer :)
Federico Russo,

@FedericoRusso - Ho fornito quei riferimenti a soluzioni software che forniscono alcune indicazioni su come implementarlo nell'hardware.
Rocketmagnet,

3
Forse: aggiungere un nono "resistore di somma" di 20 kOhm dallo stato corrente della cella centrale al punto di somma "+" dell'op-amp nel circuito di Rocketmagnet, ovvero assegnare alla cella centrale un peso di 1 e le 8 celle vicine un peso di 2. Quindi modificare il divisore di tensione in modo da "nascita" (cellula morta centrale con 3 vicini vivi; somma = 6) e "rimanere in vita" (cellula morta centrale viva con 2 o 3 vicini vivi, somma = 5 o 7) fornisce output di "01"; e tutti gli altri casi (in cui la cellula centrale muore o rimane morta) forniscono output di "00" o "11". Quindi un gate XOR fornisce lo stato successivo della cella centrale.
davidcary,

1
Alcune cose che ho scoperto facendo alcuni esperimenti: le resistenze non sono del tutto giuste. Ho trovato alcune combinazioni migliori ma sto ancora cercando di ottimizzare. Inoltre, quando si crea una griglia di questi, la corrente scorrerà all'indietro attraverso i resistori di riepilogo e rovinerà le cose. I diodi sui collegamenti sono un modo per impedirlo.
captncraig,

6

μ

La tabella di ricerca è anche solo 1 parte ed è più veloce del microcontrollore. Dimentica le EEPROM parallele, sono costose. Utilizzare un Flash parallelo a livello di byte . Questo è di 512 kByte, 2000 volte più di quello di cui hai bisogno, ma è la soluzione più economica (1 dollaro). E puoi aggiungere altre 6 funzioni a 1 bit allo stesso prezzo.

Puoi anche usare un CPLD . Scrivi la funzione in VHDL o Verilog come un'unica istruzione SOP (Sum Of Products) lunga e lascia che il sintetizzatore crei la logica.

Il registro a scorrimento è OK se è possibile attendere il risultato; questa è la soluzione più lenta.

Infine, puoi farlo con le porte logiche , ma passerai molto tempo a ridurre lo SOP nella sua forma minima se vuoi andare tutto di base. Rocketmagnet ha l'idea giusta di utilizzare gli additivi, ma i suoi numeri sono spenti: un mezzo sommatore da 1 bit fornisce 2 bit, non 3. Quindi aggiungere gli output dei due addetti due per due richiede due additivi da 2 bit, dando due 3- po 'di risultati. Utilizzare un mezzo sommatore a 3 bit per ottenere il risultato a 4 bit. Utilizzando gli additivi completi a 1 bit avrai bisogno di un solo sommatore a 2 bit.


1

I circuiti ibridi paralleli sequenziali possono essere molto più compatti dei circuiti puramente paralleli. Ad esempio, se modifichi le regole in modo tale che una casella 3x3 trasformi la cella nel punto morto centrale se ci sono meno di tre celle vive o più di quattro, e la trasformi in vita se ci sono esattamente tre celle vive (il comportamento sotto queste le nuove regole corrisponderanno all'originale), si può semplificare la logica eseguendo una sequenza in due passaggi:

tempVal [x, y] = orig [x-1, y] + orig [x, y] + orig [x + 1, y] 'Somma a due bit di tre numeri a uno-bit
orig [x, y] = LiveDeadFunc (orig [x, y], tempval [x, y-1] + tempVal [x, y] + tempVal [x, y + 1])

L'array tempVal[x,y]ha due bit per cella; quest'ultima operazione somma tre di questi numeri per produrre un valore 0-9 (sebbene tutti i valori superiori a quattro siano equivalenti), che possono quindi essere utilizzati per calcolare uno stato live / dead a bit singolo per la generazione successiva.

A proposito, un'alternativa a fare una somma aritmetica nella seconda fase ed esaminare il valore sarebbe quella di convertire tempVal [x, y] in una rappresentazione one-hot, e quindi verificare esplicitamente una delle nove combinazioni di valori che produrrebbe tre celle o una delle dodici che avrebbero prodotto quattro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.