Obter número de bits definidos na lógica digital

9

Como exercício, estou tentando projetar uma implementação do Jogo da Vida de Conway na lógica digital simples. Eu poderia fazer tudo minimizando uma função com 9 variáveis, mas imagino que ainda será bastante grande. Um dos elementos principais do algoritmo é determinar quantos de seus 8 vizinhos estão 'vivos'.

Dadas 8 entradas, qual é a maneira mais fácil de determinar quantas estão definidas? Particularmente, preciso de uma saída alta quando 2 forem definidas e uma saída alta quando 3 forem definidas.

Minha idéia principal agora consiste em um registrador de deslocamento PISO, um contador e um decodificador 3: 8, mas eu praticamente preciso de um microcontrolador para conduzir tudo isso. Não parece tão complicado de uma função. Talvez uma ROM de 256x2 também funcione, mas minhas pesquisas não apareceram nesse tipo de parte.

Eu sei que qualquer foto com 10 IO poderia fazer isso trivialmente, mas eu quero implementá-la da maneira mais mínima possível.

captncraig
fonte

Respostas:

13

Você pode encontrar vários algoritmos no esclarecimento da contagem rápida de bits . Os dois últimos: Nifty Parallel Count e MIT HAKMEM Count podem ser fáceis de converter em portões. Veja esta página para uma boa explicação de como funciona.

Você poderia fazer isso usando o hardware gates. Use quatro somadores de 1 bit para adicionar pares de bits. Isso fornece quatro números de 3 bits. Adicione-os em pares usando dois somadores de 3 bits. Isso fornece dois números de 4 bits a serem adicionados usando um somador de 4 bits. Isso deixa você com um valor de 5 bits, mas você pode ignorar o bit superior. Em seguida, use dois comparadores de 4 bits para testar os valores 2 e 3.

Para uma contagem mínima de peças, por que não fazer analógico?

Crie um divisor de tensão com um resistor na parte superior e suas 8 entradas conectadas na parte inferior por 8 resistências em paralelo. Em seguida, basta usar dois comparadores configurados para detectar os níveis de tensão que 2 ou 3 bits produzirão. São apenas 6 partes:

Detector de contagem de bits

A rede de 8 resistores produzirá uma tensão entre 0v (para conjuntos de 0 bits) e 5v (para conjuntos de 8 bits). 2 bits produzirão 0,5v. 3 bits produzirão 1,56v.

  • Com 0 ou 1 bits, a saída será 00.
  • Com 2 ou 3 bits, a saída será 01.
  • Com 4 ou mais bits, a saída será 11.

Adicionado:

Agradecemos a DavidCary por uma excelente sugestão. Depois de muito cálculo, acho que encontrei um conjunto de resistores que funcionam, mas você deve verificar cuidadosamente meus cálculos primeiro. Aqui, estou usando comparadores com saídas de dreno aberto e acho que consegui obter uma única saída. Baixo significa morto na próxima rodada, Alto significa vivo na próxima rodada.

Circuito do jogo da vida de Conway 2

O bom é que esse circuito possui apenas mais dois componentes que o outro circuito. Eles são todos os resistores da série E8, por isso deve ser possível se apossar. Além disso, R6 deveria ter um valor mais alto, como 4,7k ou algo assim.

Rocketmagnet
fonte
4
+1 apenas porque sua resposta não é "Use um microcontrolador". Esse parece ser o modo padrão por aqui.
Connor Lobo
@FakeName: a primeira referência é para soluções de software. Claro que você não tem que implementá-las em um microcontrolador, você também pode usar um supercomputador :)
Federico Russo
@FedericoRusso - dei essas referências a soluções de software que fornecem algumas dicas sobre como ele pode implementá-lo em hardware.
precisa
3
Talvez: Adicione um nono "resistor de soma" de 20 kOhm do estado atual da célula central ao ponto de soma do op-amp "+" no circuito de Rocketmagnet - ou seja, dê à célula central um peso de 1 e as 8 células vizinhas um peso de 2. Em seguida, ajuste o divisor de tensão para "nascimento" (célula morta central com 3 vizinhos vivos; soma = 6) e "permanecer vivo" (célula morta central viva com 2 ou 3 vizinhos vivos, soma = 5 ou 7) dá saídas de "01"; e todos os outros casos (em que a célula central morre ou permanece morta) fornecem saídas "00" ou "11". Em seguida, um portão XOR fornece o próximo estado da célula central.
davidcary
11
Algumas coisas que eu descobri fazendo algumas experiências: as resistências não estão certas. Encontrei algumas combinações melhores, mas ainda estou tentando otimizar. Além disso, ao fazer uma grade destes, a corrente fluirá para trás através dos summimg resistores e atrapalhará as coisas. Diodos nas interligações são uma maneira de evitar isso.
captncraig
6

O que é mínimo? O microcontrolador é apenas uma parte e pode produzir o resultado com um atraso mínimo (<1 µs). Com 54 centavos, o ATTiny20 é o microcontrolador mais barato com 10 E / S na Digikey. μ

A tabela de pesquisa também possui apenas 1 parte e é mais rápida que o microcontrolador. Esqueça as EEPROMs paralelas, elas são caras. Use um Flash paralelo em bytes . Este é de 512 kByte, 2000 vezes mais do que você precisa, mas é a solução mais barata (1 dólar). E você pode adicionar mais 6 funções de 1 bit pelo mesmo preço.

Você também pode usar um CPLD . Escreva a função em VHDL ou Verilog como uma declaração longa SOP (Sum Of Products) e deixe o sintetizador criar a lógica.

O registro de turno está OK se você pode esperar pelo resultado; esta é a solução mais lenta.

Por fim, você pode fazê-lo com portas lógicas , mas gastará muito tempo para reduzir o SOP para sua forma mínima, se quiser ir tudo básico. Rocketmagnet tem a ideia certa de usar somadores, mas seus números estão desatualizados: um meio somador de 1 bit fornece 2 bits, não 3. Portanto, adicionar as saídas dos meio adicionadores dois a dois requer dois somadores de 2 bits, dando dois resultados de bits. Use um meio somador de 3 bits para obter o resultado de 4 bits. Usando os somadores completos de 1 bit, você precisará de apenas um somador de 2 bits.

stevenvh
fonte
1

Os circuitos sequenciais paralelos híbridos tendem a ser muito mais compactos que os circuitos puramente paralelos. Por exemplo, se você ajustar as regras para que uma caixa 3x3 torne a célula no centro morta se houver menos de três células vivas ou mais de quatro e a torne viva se houver exatamente três células vivas (o comportamento sob essas Se as novas regras corresponderem ao original), é possível simplificar a lógica executando uma sequência de duas etapas:

tempVal [x, y] = orig [x-1, y] + orig [x, y] + orig [x + 1, y] 'Soma de dois bits de três números de um bit
orig [x, y] = LiveDeadFunc (orig [x, y], tempval [x, y-1] + tempVal [x, y] + tempVal [x, y + 1])

A matriz tempVal[x,y]possui dois bits por célula; a última operação soma três desses números para produzir um valor de 0 a 9 (embora todos os valores superiores a quatro sejam equivalentes), que podem então ser usados ​​para calcular um status de ativo / morto de um bit para a próxima geração.

BTW, uma alternativa para fazer uma soma aritmética no segundo estágio e examinar o valor seria converter tempVal [x, y] em uma representação quente e, em seguida, verificar explicitamente uma das nove combinações de valores que produziriam três células, ou um dos doze que produziria quatro.

supercat
fonte