Verilog 101: Construindo Seus Primeiros Módulos de Descrição de Hardware
Neste artigo, estudaremos a estrutura básica de um módulo Verilog, veremos exemplos de uso do tipo de dado "wire" do Verilog e sua forma vetorial, e tocaremos brevemente em algumas diferenças entre VHDL e Verilog.
Neste artigo, estudaremos a estrutura básica de um módulo Verilog, veremos exemplos de uso do tipo de dado "wire" do Verilog e sua forma vetorial, e tocaremos brevemente em algumas diferenças entre VHDL e Verilog.
Verilog e VHDL são duas linguagens comumente usadas para descrever circuitos digitais. O AAC tem uma série de artigos técnicos discutindo os conceitos básicos de VHDL. Este artigo funciona como ponto de partida para nossa série sobre Verilog.
Preciso de Ambos Verilog e VHDL?
Antes de iniciar nossa discussão, vamos abordar uma pergunta óbvia: realmente precisamos conhecer ambas as linguagens?
Tanto Verilog quanto VHDL são ferramentas poderosas que podem ser usadas para projetar um circuito digital complexo. Embora existam algumas diferenças entre estes dois HDLs, você é livre para escolher um para dominar e usar. No entanto, acredito que em algum ponto você se beneficiará de ter pelo menos um entendimento básico de ambas as linguagens. Às vezes, como designers, precisamos de um trecho de código de exemplo para ter uma ideia sobre como codificar um projeto. Navegamos na rede por horas e finalmente encontramos o que precisamos, mas não faz sentido para nós – está escrito no HDL que é completamente desconhecido para nós. Sem ter um entendimento básico da linguagem, podemos não ser capazes de entender completamente as técnicas.
Evolução do Verilog
Verilog foi projetado no início de 1984 pela Gateway Design Automation (cerca de três anos após o VHDL ter sido iniciado pelo Departamento de Defesa dos EUA). Com o apoio do DoD, o VHDL tornou-se um padrão IEEE em 1987. O Verilog não entrou em cena até 1995. Hoje, tanto VHDL quanto Verilog são HDLs populares e ferramentas de design FPGA geralmente suportam ambas as linguagens.
A palavra "Verilog" é uma junção das palavras "verification" e "logic" porque a linguagem foi sugerida pela primeira vez como uma ferramenta de simulação e verificação. Vamos começar com conceitos e sintaxe do Verilog.
Exemplo 1
Como primeiro exemplo, vamos escrever o código Verilog para o circuito representado na Figura 1.

Figura 1. Circuit_1
Existem duas entradas e uma saída. As portas são todas de um bit de largura. A funcionalidade do circuito é fazer AND das duas entradas e colocar o resultado na porta out1.
Uma possível descrição Verilog para o módulo Circuit_1 é:

Linhas 1 e 8
Estas duas linhas usam as palavras-chave "module" e "endmodule" para especificar que as linhas entre elas (linhas 2 a 7) descrevem um circuito chamado "Circuit_1". Este nome é arbitrário e nos permite referenciar este circuito posteriormente.
Linhas 2 a 6
Estas linhas especificam a interface do "Circuit_1" com seu ambiente circundante. As portas de entrada e saída são descritas usando as palavras-chave "input" e "output". Estas palavras-chave são seguidas por outra palavra-chave "wire" e então o nome da porta (Veja Figura 1). O que a palavra-chave "wire" especifica? "Wire" é um tipo de dado Verilog que representa um fio físico no design. Discutiremos os tipos de dados Verilog em maior detalhe em um artigo futuro, mas por enquanto sabemos que haveriam três fios chamados a, b e out1 em nosso módulo e, como são especificados na declaração de porta, correspondem à interface do módulo.
Linha 7
Esta linha usa o operador AND bit a bit, ou seja, &, para descrever a funcionalidade do circuito. A palavra-chave "assign" coloca a&b na porta de saída out1. Este tipo de atribuição é chamado de atribuição contínua. É chamado assim porque a atribuição está sempre ativa sempre que um operando no lado direito muda, a&b é avaliado e atribuído a out1. Podemos vislumbrar uma atribuição contínua como um circuito combinacional cuja saída é continuamente atualizada dependendo de suas entradas. No nosso exemplo, este circuito combinacional é uma simples porta AND. Existem também atribuições processuais em Verilog HDL que serão discutidas em artigos futuros.
Agora, podemos usar um pacote de software como Xilinx ISE para verificar o código acima. Você pode encontrar um tutorial baseado em Verilog deste software aqui (PDF).
Comparando Exemplo 1 com Código VHDL
A Figura 2 abaixo mostra as descrições Verilog e VHDL para o módulo Circuit_1.

Figura 2. Comparação das descrições Verilog e VHDL para Circuit_1.
Como você pode ver, temos que incluir algumas bibliotecas ao codificar em VHDL. Estas bibliotecas dão a definição para os tipos de dados e operadores. Considerando a adição dessas bibliotecas e o formato geral do VHDL, observamos que o código VHDL é mais verboso. No entanto, esta verbosidade não é sem vantagens. Por exemplo, o recurso de gerenciamento de bibliotecas do VHDL pode ser útil ao modelar sistemas de nível superior. Em artigos futuros, ocasionalmente discutiremos os prós e contras destes dois HDLs.
Verilog tem um Sistema de Quatro Valores
Existem quatro valores básicos usados na maioria dos tipos de dados Verilog. Os fios definidos no Listing 1 podem assumir um dos seguintes valores:
- 0: para uma condição lógica baixa ou falsa
- 1: para uma condição lógica alta ou verdadeira
- z: para o estado de alta impedância (pode ser usado para descrever a saída de um buffer tri-state)
- x: para um valor don't-care ou desconhecido (quando uma entrada não é inicializada ou duas ou mais saídas conflitantes são conectadas juntas).
O tipo de dado VHDL std_logic pode assumir nove valores diferentes, mas seus valores comumente usados são '0', '1', 'Z' e '-' ('-' denota um don't care).
Exemplo 2
Como outro exemplo, vamos escrever o código Verilog para o circuito (que rotularemos Circuit_2) mostrado na Figura 3.

Figura 3. Circuit_2
O seguinte código Verilog descreve este circuito:

Os elementos usados no código acima são semelhantes aos do Exemplo 1, exceto que um sinal interno é definido na linha 10 do código. A palavra-chave "wire" é usada para especificar o tipo de dado desta conexão. Como discutido acima, o tipo de dado "wire" se traduziria em um fio físico no design.
O código acima também usa alguns novos operadores bit a bit do Verilog: ~ para NOT e | para operação OR. Outro operador bit a bit útil é ^ para operação XOR. A Figura 4 mostra tanto as descrições Verilog quanto VHDL para o módulo Circuit_2. Tais comparações podem ajudá-lo a ver as diferenças e semelhanças entre estas duas linguagens.

Figura 4. Comparação das descrições Verilog e VHDL para Circuit_2.
Exemplo 3
Para nosso terceiro e último exemplo, daremos o código Verilog para o esquemático mostrado na Figura 5.

Figura 5. Esquemático para exemplo 3.
Como você pode ver, existe uma certa relação entre as portas de entrada azuis e as vermelhas: as entradas correspondentes são combinadas com o operador AND. O resultado é atribuído a uma porta de saída. Em tais casos, podemos agrupar os sinais e tratá-los como um vetor. Isso torna o código compacto e legível.
Usando o conceito de vetor em Verilog, podemos facilmente estender o código do Listing 1 para descrever o circuito acima (Veja o código no Listing 3 abaixo).

Note que o intervalo de índice dos vetores pode ser ascendente ([0:2] como usado acima) ou descendente ([2:0]). Embora o formato ascendente seja usado acima, geralmente é menos propenso a erros usar a forma descendente. Isso se deve ao fato de que o estilo descendente corresponde à nossa percepção de que a posição mais à esquerda de um número binário tem o índice mais alto. Note que vetores também são usados em VHDL.
A Figura 6 abaixo mostra uma simulação ISE do código no Listing 3.

Figura 6. Simulação ISE do código do Exemplo 3.
Neste artigo, discutimos que é uma boa ideia aprender tanto VHDL quanto Verilog, estudamos a estrutura básica de um módulo Verilog, e nos familiarizamos com o tipo de dado "wire" do Verilog e sua forma vetorial. Também tocamos brevemente em algumas diferenças entre VHDL e Verilog. O próximo artigo em nossa série Verilog discutirá o design de circuitos combinacionais em Verilog.
Integrado
- Contêineres Code-Ready: Guia Prático para Automação de Processos Cloud-Native com Red Hat OpenShift
- Guia Prático de Impressão 3D em Cerâmica: Técnicas, Materiais e Dicas de Design
- Primeiros Passos com TJBot: Construa, Configure e Controle por Voz seu Próprio Robô de IA
- Guia Passo a Passo para Implantar Gateway LoRa RAK 831 no Raspberry Pi 3
- Construa um Gateway LoRa com Módulo RAK831 no Raspberry Pi 3 – Guia Passo a Passo
- Domine Inferencing Edge AI: Guia Prático para Insights Acionáveis
- Conheça o Eagle Group: Seu Parceiro para Fabricação de Metais de Qualidade
- Otimize Máquinas Cat®: O Guia Definitivo do My.Cat.com
- Implantando Node-RED no PLCnext com Docker: Guia Passo a Passo
- Construa Sua Primeira Aplicação Go no PLCnext: Guia para Iniciantes