Índice:

VHDL Basys3: Conecte 4 jogos: 5 etapas
VHDL Basys3: Conecte 4 jogos: 5 etapas

Vídeo: VHDL Basys3: Conecte 4 jogos: 5 etapas

Vídeo: VHDL Basys3: Conecte 4 jogos: 5 etapas
Vídeo: Getting started with Vivado and Basys3 2024, Novembro
Anonim
VHDL Basys3: Connect 4 Game
VHDL Basys3: Connect 4 Game

Introdução:

Este é um Connect 4 Digital Logic Game projetado em VHDL usando o software Vivado e programado para o Basys3 Board. A construção e o desenho deste projeto são intermediários, mas os novatos podem copiar as etapas e construir o jogo digital.

O jogo funciona como o jogo Connect 4. Os jogadores podem mover o cursor pela tela usando os botões esquerdo e direito encontrados no tabuleiro. Pressionar o botão do meio no tabuleiro fará com que o jogador coloque seu marcador naquela coluna e então será a vez do próximo jogador. Quando um jogador ganha, o jogo pode ser reiniciado pressionando o botão para cima no tabuleiro.

Etapa 1: Detalhes e materiais rápidos

Detalhes técnicos rápidos:

  • Utiliza três conjuntos de conexões PMOD na placa (JA, JB, JC)

    • 8 pinos (excluindo pinos Vcc e GND) usados para cada conector PMOD
    • JA - Controle de Linhas
    • JB - Controle de Colunas Verdes
    • JC - Controle de Colunas Vermelhas
  • O relógio da tela opera a 960 Hz

    Apenas 8 LEDs estão acesos em um determinado momento. A tela é atualizada a uma velocidade de clock rápida o suficiente para que se tenha a ilusão de que mais de 8 LEDs estão acesos em um determinado momento

  • O relógio do botão opera a 5 Hz; Opcionalmente, pode ser ajustado editando o código VHDL.
  • A resistência interna dos Darlington Arrays é suficiente para evitar a queima do LED

O jogo é construído usando os seguintes componentes e ferramentas:

  • (1) Placa Basys3
  • (2) Matriz LED bicolor 8x5:
  • (2) ULN2803 - Matrizes de transistores Darlington - Folha de dados
  • Carretéis de Arame
  • Jumper Wires
  • Decapador de Arame
  • Pranchas de pão (um quadrado grande deve ser suficiente)
  • Multímetro e fonte de alimentação (solução de problemas)

Etapa 2: Conectando o Hardware

Conectando o Hardware
Conectando o Hardware
Conectando o Hardware
Conectando o Hardware

Diretrizes:

A fiação do projeto pode ser extremamente complicada, por favor, reserve um tempo e verifique se todas as conexões estão corretas, uma de cada vez.

O projeto envolve o uso de duas telas de LED, mas são combinadas para formar uma tela grande. Isso pode ser feito conectando todas as linhas ao mesmo ponto. Como cada tela é bicolor, as linhas vermelhas e verdes de uma tela também devem ser vinculadas às linhas vermelhas e verdes da outra tela. Fazendo isso, podemos controlar todas as linhas com apenas 8 pinos. Os outros 16 pinos são usados para controlar as colunas da tela. Os 8 pinos para o podem ser conectados diretamente por meio de cabos jumper aos conectores pmod. As conexões Pmod vão primeiro para a entrada do ULN2083A e a saída do ULN2083A é conectada diretamente à coluna na tela. Como o design é 8x8, algumas colunas não estarão fisicamente conectadas.

  • JA: Conexões de linha: Linha 1 para JA: 1 para Linha 8 para JA: 10.
  • JA: Conexões de coluna vermelha:
  • JC: Conexões da Coluna Verde

Consulte as imagens postadas para saber quais pinos correspondem a quais linhas / colunas.

Nota: Os transistores possuem resistências embutidas, então os LEDs não requerem resistência adicional para serem conectados a eles em série.

Etapa 3: Explicação técnica: Tela

A tela está operando na persistência da visão. A tela é atualizada tão rápido que o olho humano não consegue detectar visivelmente que alguns LEDs estão sendo desligados e ligados rapidamente. Na verdade, diminuindo a velocidade do relógio de exibição, pode-se notar que ele está piscando.

A exibição liga todas as oito linhas de acordo com os dados armazenados para essas linhas, e a exibição liga uma coluna. Em seguida, ele faz a transição rápida para a próxima entrada de dados para as oito linhas e ativa a próxima coluna - enquanto todas as outras colunas estão desativadas. Este processo continua a uma velocidade de clock suficientemente rápida para que a cintilação do LED se torne imperceptível.

O armazenamento de dados para a exibição é inicializado imediatamente após a arquitetura no arquivo VHDL da seguinte maneira:

sinal RedA, RedB, RedC, RedD, RedE, RedF, RedG, RedH: std_logic_vector (7 downto 0): = "00000000";

sinal VerdeA, VerdeB, VerdeC, VerdeD, VerdeE, VerdeF, VerdeG, VerdeH: std_logic_vector (7 downto 0): = "00000000"; - Dados de linha dependendo da coluna: VERDE

A seguir, um pequeno trecho do processo que controla a matriz de exibição de LED.

- Processo que controla a exibição da matriz de LED: processo (ColCLK) - 0 - 16 para atualizar a variável de matriz 8X8 RED e 8x8 GREEn RowCount: intervalo inteiro de 0 a 16: = 0; começar if (rise_edge (ColCLK)) then if (RowCount = 0) then DORow <= RedA; - Dados de linha para a coluna DOCol correspondente <= "1000000000000000"; - Coluna Trigger - Repita este código até "0000000000000001" - Mude para RedB, RedC… GreenA, GreenB… GreenH

No final do GreenH, logo antes de o processo terminar, este trecho é incluído para redefinir o RowCount de volta para zero.

if (RowCount = 15) then - Reinicia a atualização da coluna A RowCount: = 0; senão RowCount: = RowCount + 1; - Deslocar pelo final das colunas se;

Agora, para explicar o relógio que está na lista de sensibilidade do processo de exibição. A placa Basys3 possui um clock interno operando a 100MHz. Para nossos propósitos, este é um clock muito rápido, então precisaremos dividir esse clock em um clock de 960 Hz usando o seguinte processo.

- Processo de relógio operando em 960HzCLKDivider: variável de processo (CLK) clkcount: faixa inteira de 0 a 52083: = 0; começar if (rise_edge (CLK)) then clkcount: = clkcount + 1; if (clkcount = 52083) então ColCLK <= not (ColCLK); clkcount: = 0; fim se; fim se; fim do processo;

Etapa 4: Explicação técnica: Alterando as informações exibidas

Explicação técnica: Alterando as informações exibidas
Explicação técnica: Alterando as informações exibidas

No código VHDL, as informações ou dados que serão exibidos na tela são controlados pelo processo do cursor, que possui um relógio diferente em sua lista de sensibilidade. Esse código foi chamado de BtnCLK, um relógio projetado para minimizar o desbocamento dos botões quando eles são pressionados. Isso é incluído para que, se um botão for pressionado, o cursor na linha superior não se mova muito rapidamente pelas colunas.

- Processo de relógio operando a 5 Hz. ButtonCLK: variável de processo (CLK) btnclkcount: intervalo inteiro de 0 a 10000001: = 0; comece if (rise_edge (CLK)) then if (btnclkcount = 10000000) then btnclkcount: = 0; BtnCLK <= não (BtnCLK); else btnclkcount: = btnclkcount + 1; fim se; fim se; fim do processo;

Com a saída do sinal BtnCLK desse processo, podemos agora explicar o processo do cursor. O processo do cursor só tem BtnCLK em sua lista de sensibilidade, mas no bloco de código, o estado dos botões é verificado e isso fará com que os dados de RedA, RedB … GreenH sejam alterados. Aqui está um fragmento do código do cursor, que inclui o bloco de reinicialização e o bloco da primeira coluna.

cursor: variável de processo (BtnCLK) OCursorCol: STD_LOGIC_VECTOR (2 até 0): = "000"; - OCursorCol mantém o controle da variável de coluna anterior NCursorCol: STD_LOGIC_VECTOR (2 até 0): = "000"; - NCursorCol define o início da nova coluna do cursor - Condição RESET (botão PARA CIMA) --O tabuleiro é limpo para o jogo reiniciar se (crescendo_edge (BtnCLK)) então se (RST = '1') então RedA <= "00000000"; RedB <= "00000000"; RedC <= "00000000"; RedD <= "00000000"; RedE <= "00000000"; RedF <= "00000000"; RedG <= "00000000"; RedH <= "00000000"; VerdeA <= "00000000"; GreenB <= "00000000"; GreenC <= "00000000"; GreenD <= "00000000"; VerdeE <= "00000000"; GreenF <= "00000000"; GreenG <= "00000000"; GreenH if (Lbtn = '1') then NCursorCol: = "111"; - Coluna H elsif (Rbtn = '1') então NCursorCol: = "001"; - Coluna B elsif (Cbtn = '1') então NCursorCol: = OCursorCol; - A coluna permanece o mesmo NTurnState <= não (TurnState); - Aciona a vez do próximo jogador - Verifica a coluna atual de baixo para cima e acende o primeiro LED que não está aceso. A cor depende da cor do cursor do jogador atual. para ck em 7 até 1 loop if (RedA (0) = '1') e (RedA (ck) = '0') e (GreenA (ck) = '0') then RedA (Ck) <= '1'; RedA (0) <= '0'; SAÍDA; fim se;

if (GreenA (0) = '1') e (RedA (ck) = '0') e (GreenA (ck) = '0') então

GreenA (Ck) <= '1'; VerdeA (0) - Jogador Vermelho VerdeA (0) <= '0'; if (NCursorCol = OCursorCol) then - Se nada foi pressionado RedA (0) <= '1'; elsif (NCursorCol = "111") then - Se Lbtn foi pressionado RedH (0) <= '1'; RedA (0) <= '0'; elsif (NCursorCol = "001") então - Iff Rbtn foi pressionado RedB (0) <= '1'; VermelhoA (0) - Jogador Verde VermelhoA (0) <= '0'; if (NCursorCol = OCursorCol) então GreenA (0) <= '1'; elsif (NCursorCol = "111") então GreenH (0) <= '1'; VerdeA (0) <= '0'; elsif (NCursorCol = "001") então GreenB (0) <= '1'; VerdeA (0) <= '0'; fim se; caso final;

Observe, a primeira instrução case chamada: OCursorCol (que significa Old Cursor Column) é o início da máquina de estado finito. Cada coluna do display é tratada como seu próprio estado no FSM. Existem 8 colunas, portanto, um conjunto de números binários de 3 bits foi usado para identificar cada coluna como um estado. O modo como o FSM se move entre os estados depende do botão que é pressionado. No trecho acima, se o botão esquerdo for pressionado, o FSM se moverá para "111", que seria a última coluna do display. Se o botão direito for pressionado, o FSM se moverá para "001", que seria a segunda coluna do display.

Se o botão do meio for pressionado, o FSM NÃO se moverá para um novo estado, mas, em vez disso, acionará uma mudança no sinal TurnState, que é um sinal de um bit para observar qual é a vez do jogador. Além disso, o botão do meio executará um bloco de código que verifica se há uma linha vazia na parte inferior até o topo. Ele tentará colocar um marcador na linha inferior não preenchida. Lembre-se, este é um jogo de quatro conectores.

Na instrução case aninhada chamada: TurnState, alteramos a cor do cursor e para qual coluna da primeira linha desejamos alterar os dados para que o processo de exibição possa refletir a alteração.

Repetimos esse código básico para os sete casos restantes. O diagrama FSM pode ser útil para entender como os estados estão mudando.

Etapa 5: Código

Código
Código

Este é o código funcional do Connect 4 que pode ser compilado em VHDL usando o software Vivado.

Uma restrição também é fornecida para permitir que você coloque o jogo em execução.

Fornecemos um diagrama de blocos que explica como as entradas e saídas de cada processo estão interconectadas.

Recomendado: