Olá, aluno(a)! Se estamos estudando computação, estamos aprendendo sistemas digitais. Para construir bons sistemas, é importante lembrar de que não basta saber programar e ter lógica: também é preciso se atentar à construção e ao uso de circuitos digitais. Uma das ferramentas que tem sido utilizada para isso são as linguagens de descrição de hardware (Hardware Description Language - HDL). É isso que o aprenderemos nesta lição!
Suponha que você queira criar um circuito lógico para uma montadora que deseja que o carro emita um alerta toda vez que o cinto de segurança não estiver sendo usado. Como você construiria essa solução?
Nós já estudamos a lógica booleana, a álgebra das proposições e os circuitos. Você deveria começar tentando pensar em como estruturar o problema. Tocci, Widmer e Moss (2007) explicam o seguinte:
Se o motorista estiver presente E NÃO estiver usando o cinto E a ignição estiver acionada, ENTÃO, emita um sinal sonoro.
Poderíamos construir um circuito lógico para a situação anterior, não é? Ele teria uma porta AND ligada à situação do motorista presente e à ignição ligada. Além disso, precisaria de um NAND para representar que o cinto não está em uso.
Entretanto, emerge a seguinte questão: como transmitir todas essas informações para o computador?
Você já parou para pensar sobre o conceito diferente de linguagem que estamos estudando? As linguagens de descrição de hardware têm por objetivo descrever a configuração do hardware de um circuito. Durante algum tempo, eu não conseguia assimilá-las, porque, até então, eu somente tinha conhecido as linguagens de programação mais comuns que são criadas para representar uma sequência de instruções para alguma tarefa ser executada pelo computador.
Quando passei a entender a diferença dos objetivos que elas carregam, tudo fez sentido! Perceba que ambas são úteis para programar um dispositivo. No entanto, os computadores são formados por vários circuitos lógicos e operam seguindo uma lista de tarefas (programa) que são executadas sequencialmente.
Dessa maneira, ficou mais fácil, não é mesmo? Conseguimos perceber que o computador, ao executar instruções, sempre realizará uma por vez, mas com uma velocidade enorme. Para nós, há a sensação de que ele executa simultaneamente.
Por outro lado, um circuito lógico digital é limitado pela velocidade de acordo com a rapidez com que o circuito consegue variar as saídas em resposta às variações nas entradas. Com isso, identificamos a importância de saber como o HDL pode ser útil em sistemas digitais.
Tocci, Widmer e Moss (2007, p. 84) argumentam que um computador nada mais é que “uma combinação de areia processada e fios de metal que não tem a menor ideia do que você quer dizer, então você precisa apresentar as instruções usando a linguagem que o computador espera e entende”.
O formato para uma descrição de circuito de hardware envolve:
Especificações de entrada.
Especificações de saída.
Operação (resposta das saídas às entradas realizadas).
Portanto, imagine que se você terá duas entradas. Cada uma delas precisa ser referenciada ou ter um nome. O circuito que você utilizará também precisa.
Vamos dar um exemplo?
Pense em um alarme de carro ou de uma casa. Você precisa apenas de um único bit, não é? Ligado (1) ou desligado (0). Seria um botão alternador de ativar ou desativar.
Totalmente diferente seria se tivéssemos uma entrada com 4 bits. Nesse caso, ele teria até 16 entradas ou arranjos diferentes. Portanto, pensar nas possíveis e necessárias entradas é muito importante para o seu projeto.
A Figura 1 ilustra a ideia de um formato de arquivos HDL.
Figura 1 - Formato de arquivos HDL
Fonte: adaptada de Tocci, Widmer e Moss (2007).
#PraCegoVer: a figura tem fundo azul e é representada por um retângulo grande com três retângulos menores dispostos em vertical um abaixo do outro. O retângulo do topo se chama “Documentação”, o do meio se chama “Definições de Entrada e Saída” e o da base se chama “Descrição Funcional”.
Assim como você pode observar, a figura apresenta o formato de arquivos HDL. Nesse tipo de linguagem, é fundamental estabelecer as relações de entrada e saída, pois, dessa forma, é possível definir a operação do circuito em uma linguagem de acordo com o conjunto de declarações que seguem as definições criadas para o circuito.
Para exemplificar o uso, podemos voltar ao nosso exemplo do circuito de duas entradas. Nesse caso, ele terá uma porta AND, que, por ser uma conjunção, somente será verdade se ambas as entradas forem 1. Nesse sentido, terá uma saída.
Como ficaria, então, em uma linguagem chamada AHDL?
O Quadro 1, de Tocci, Widmer e Moss (2007), dá-nos a resposta.
Quadro 1 - Elementos essenciais em AHDL
Fonte: adaptado de Tocci, Widmer e Moss (2007).
#PraCegoVer: o quadro possui fundo branco e contém o seguinte conteúdo indentado como uma linguagem de programação: a linha 1 tem o conteúdo “SUBDESIGN and_gate”. A linha 2 tem “(“. A linha 3 tem “a, b: INPUT;”. A linha 4 tem “y: OUTPUT;”. A linha 5 tem “)”. A linha 6 com “BEGIN”. A linha 7 tem “y = a & b;” e a linha 8 tem “END;”.
A palavra-chave SUBDESIGN dá nome ao bloco do circuito que, no exemplo, é uma porta AND ou (and_gate). O nome do arquivo poderia ser, por exemplo, and_gate.tdf.
Essa seção define o que seria a entrada e a saída do bloco do circuito lógico, que, na verdade, faz parte de outra estrutura ou está contido dentro de um dispositivo.
Os bits de entrada e saída foram declarados ou criados como variáveis, que são a, b e y. Eles precisam ser indicados em relação ao que são. Assim como você viu em nosso caso, a, b são entradas ou INPUTS e y é saída ou OUTPUT.
Assim, o conjunto descrito no quadro representa as declarações necessárias para a operação do circuito AHDL (que poderia ser traduzido como um compilador da linguagem AHDL da Altera). Esse conjunto está entre as palavras reservadas BEGIN e END.
Dessa maneira, a operação do hardware é descrita de forma simples, em que temos a saída, que é y, que recebe como atribuição, por meio do sinal de igual (=), o resultado de a AND b. A isso, chamamos de Declaração de Atribuição Concorrente.
A título de conhecimento, os operadores booleanos básicos são:
& - AND
# - OR
! - NOT
$ - XOR
Vamos avançar e verificar os novos elementos em VHDL. Observe o Quadro 2, assim como evidencia Tocci, Widmer e Moss (2007).
Quadro 2 - Elementos essenciais em VHDL /
Fonte: adaptado de Tocci, Widmer e Moss (2007).
#PraCegoVer: o quadro apresenta oito linhas com o seguinte conteúdo a partir da linha 1: “ENTITY and_gate IS”. Linha 2: “PORT (a,b : IN BIT;”. Linha 3: “y: OUT BIT);”. Linha 4: “END and_gate;”. Linha 5: “ARCHITETURE ckt OF and_gate IS”. Linha 6: “BEGIN”. Linha 7: “ y < = a AND b;” e a linha 8: “END ckt;”.
Assim como é visível, a palavra ENTITY fornece nome ao bloco do circuito and_gate. O fato de algumas palavras estarem em maiúsculas e outras em minúsculas se dá pelo uso de um estilo de escrita que torna mais fácil ler o código e segue o que é pedido no compilador da Altera para VHDL.
Logo em seguida, temos a palavra PORT, que indica a definição de entradas e saídas para o bloco de circuito. Depois, é possível ver os nomes das entradas e uma descrição do modo e do tipo de entrada.
A descrição BIT significa que cada variável da lista é um bit único (1 ou 0).
A declaração ARCHITETURE pode ser usada quando precisamos descrever a operação de todos os aspectos que estão contidos no bloco. Assim, todo ENTITY precisa ter, pelo menos, um ARCHITETURE (que, nesse caso, recebeu o nome de ckt).
Em nosso exemplo, entre o BEGIN e o END, temos a descrição da arquitetura. Nela, há uma equação de álgebra booleana que declara que a saída (y) recebe como atribuição (< =) o nível lógico produzido por a AND b. A ela, chamamos de declaração de atribuição concorrente. Isso, porque tudo o que está dentro do BEGIN e do END é avaliado de forma constante e concorrentemente.
Com isso, pudemos aprender um pouco as Linguagens de Descrição de Hardware. Elas facilitam bastante os projetos em que queremos uma aplicabilidade e que se tornam sistemas digitais. As aplicações são inúmeras e estão em todo lugar. Portanto, aproveite para pensar em como você poderia, por exemplo, projetar algo que faz parte do seu dia a dia.
Algo muito útil na programação é o uso de comentários para explicar o código criado. Embora pareça algo simples, muitos programadores, com o passar do tempo, deixam de comentar o código e o resultado é que, muitas vezes, quando é necessário realizar alguma manutenção, como uma nova funcionalidade ou mesmo atualização que envolva aquele trecho do código, leva-se muito mais tempo.
Todas as linguagens de programação já preveem o uso de comentários. Todas elas têm um formato permitido para tal.
Até mesmo em VHDL é possível criar comentários. Nessa linguagem, os comentários são sempre precedidos de dois traços (- -). Assim, o texto, após os traços e até o final da linha, inclui informações inseridas pelo projetista ou programador. O programa, ao ser compilado, ignora os comentários, ou seja, ignora tudo que está após os dois traços.
No entanto, qualquer pessoa que tiver acesso ao código poderá ler os comentários que o explicam.
Vamos ver um exemplo em VHDL:
PORT ( a,b : IN BIT; - - define entradas do bloco
y : OUT BIT); - - define a saída do bloco
Viu como é simples? Simples, mas extremamente útil para todo e qualquer programador.
TOCCI, R. J.; WIDMER, N. S.; MOSS, G. L. Sistemas digitais: princípios e aplicações. São Paulo: Pearson Prentice Hal, 2007.