
Como projetar circuitos estruturados em Verilog
Atualizado: 8 de nov. de 2022
Um projeto estruturado permite o desenvolvimento de sistemas complexos a partir de subsistemas mais simples. Utilizando-se do conceito de hierarquia, é possível compor circuitos com uma infinidade de subcircuitos mais simples, tornando o todo um sistema muito mais complexo. Neste tutorial, iremos estruturar o projeto "Olá Mundo", utilizando a hierarquia de módulos em Verilog.

Neste tutorial, você vai aprender a:
reprojetar o circuito "Ola Mundo" através de subsistemas (ou módulos)
criar módulos em Verilog para cada um dos circuitos que imprime as letras 'O', 'L' e 'A' no display da placa Community
estruturar um projeto hierárquico utilizando construções em Verilog
mapear as portas do circuito para o display da placa Community
compilar e prototipar um projeto hierárquico na placa Community
ler e compreender o relatório resumido do projeto
interagir com um projeto hierárquico na placa Community
Clique no link abaixo para baixar o código para este tutorial:
Antes de prosseguir, recomendamos os seguintes tutoriais
Reprojetando o circuito "Ola Mundo"
O circuito "Ola Mundo" possui um único arquivo Verilog contendo toda a descrição do circuito. Para reprojetá-lo de forma estruturada, precisamos decidir quais partes do circuito serão transformados em módulos (ou subsistemas). Neste tutorial, vamos modularizar os circuitos relacionados com cada uma das letras; e começaremos modularizando o subcircuito que ativa/desativa os segmentos que compõe a letra 'L'. Para isso, iremos substituir os 3 buffers indicados na figura abaixo por um módulo chamado de 'letra_l'.

Na figura acima, os três sinais de saída dos buffers foram substituídos por um barramento de 3 bits de largura. Essa alteração foi realizada para simplificar o esquemático, e é comumente encontrada em projeto de circuitos digitais. Tabelas também são muito utilizadas em circuitos digitais. Através delas, descrevemos a interface de módulos. A exemplo disso, segue descrição da interface do módulo 'letra_l':
Porta | Direção | Bits | Descrição |
ativa | entrada | 1 | Ativa os 3 segmentos necessários para a imprimir a letra 'L' no display. |
dp_seg[2:0] | saída | 3 | Sinais que compõem a letra 'L' em um display de sete segmentos. |
Descrevendo os módulos em Verilog
Com o projeto do módulo 'letra_l' encerrado, podemos partir para a implemetação em código Verilog. Abaixo, segue a descrição do módulo:
module letra_l(
// Sinal de entrada conectado a chave
// que ativa a letra 'L'
input ativa,
// Sinais de saida conectados ao display
// de sete segmentos que compoem a letra 'L'
output [2:0] dp_seg
);
// Circuito que ativa os
// segmentos que compoem a letra 'L'
buf(dp_seg[2],ativa);
buf(dp_seg[1],ativa);
buf(dp_seg[0],ativa);
endmodule
Salve o código acima em um arquivo chamado letra_l.v. Seguindo o mesmo procedimento, tente descrever por você mesmo os módulos 'letra_o' e 'letra_a', salvando-os em arquivos 'letra_o.v' e 'letra_a.v', respectivamente. Caso não consiga, o código para ambos os módulos encontra-se logo abaixo:
letra_o.v
module letra_o(
// Sinal de entrada conectado a chave
// que ativa a letra 'O'
input ativa,
// Sinais de saida conectados ao display
// de sete segmentos que compoem a letra 'O'
output [5:0] dp_seg
);
// Circuito que ativa os
// segmentos que compoem a letra 'O'
buf(dp_seg[5],ativa);
buf(dp_seg[4],ativa);
buf(dp_seg[3],ativa);
buf(dp_seg[2],ativa);
buf(dp_seg[1],ativa);
buf(dp_seg[0],ativa);
endmodule
letra_a.v
module letra_a(
// Sinal de entrada conectado a chave
// que ativa a letra 'A'
input ativa,
// Sinais de saida conectados ao display
// de sete segmentos que compoem a letra 'A'
output [5:0] dp_seg
);
// Circuito que ativa os
// segmentos que compoem a letra 'A'
buf(dp_seg[5],ativa);
buf(dp_seg[4],ativa);
buf(dp_seg[3],ativa);
buf(dp_seg[2],ativa);
buf(dp_seg[1],ativa);
buf(dp_seg[0],ativa);
endmodule
Criando a hieraquia de módulos
Agora que cada um dos módulos 'letra_o', 'letra_l' e 'letra_a' estão descritos em Verilog, precisamos criar um outro arquivo para instanciá-los. Este arquivo é chamado de ola_mundo.v, e é o arquivo topo da hierarquia. Em outras palavras, o arquivo topo é o que instancia todos os outros arquivos, conforme indicado no esquemático abaixo.

Módulos no arquivo topo podem ser instânciados através da seguinte sintaxe:
nome_do_modulo nome_da_instancia(
.porta_do_modulo(sinal_mapeado),
.porta_do_modulo(sinal_mapeado),
...
.porta_do_modulo(sinal_mapeado)
);
Aplicando a sintaxe no esquemático acima, obtemos o seguinte código para o arquivo ola_mundo.v:
module ola_mundo(
// Sinais de entrada conectados as chaves
// sw2, sw1 e sw0 da placa Pitanga
input chave_o,
input chave_l,
input chave_a,
// Sinais de saida conectados aos displays
// de sete segmentos da placa Pitanga
output [5:0] O,
output [2:0] L,
output [5:0] A
);
// Circuito que liga e desliga os
// segmentos que compoem a letra 'O'
letra_o DISPLAY_O(
.ativa(chave_o),
.dp_seg(O)
);
// Circuito que liga e desliga os
// segmentos que compoem a letra 'L'
letra_l DISPLAY_L(
.ativa(chave_l),
.dp_seg(L)
);
// Circuito que liga e desliga os
// segmentos que compoem a letra 'A'
letra_a DISPLAY_A(
.ativa(chave_a),
.dp_seg(A)
);
endmodule
Mapeando as portas na placa Community
O circuito hierarquizado está pronto, mas falta o arquivo de pinagem (.pinout) para poder prototipá-lo na placa Community. Esta etapa segue os mesmos passos do tutorial anterior. De toda a forma, colocamos o arquivo ola_mundo.pinout abaixo para a sua conveniência.