3. DESENVOLVIMENTO DO SISTEMA PROPOSTO
3.3. Desenvolvimento do Sistema
3.3.3. Projeto de Hardware (FPGA)
Considerando uma câmera digital industrial padrão, as interfaces de saída disponíveis poderiam ser uma porta Ethernet e uma porta HDMI. A porta de rede seria para enviar dados para um servidor de processamento (host). Já a porta de vídeo, poderia ser ligada a uma tela ou monitor próximo a câmera. Tal procedimento se aplica quando é necessário um operador monitorar a aquisição em tempo real ou para facilitar a etapa de calibração do sistema.
A Figura 37 mostra a arquitetura de hardware simplificada de uma câmera padrão. Note que o caminho dos dados (data path) passa por um divisor que abre dois novos caminhos. Um deles vai servir apenas para mostrar o vídeo no monitor, enquanto o segundo vai passar por mais etapas de processamento e será enviado para a porta de comunicação. Os blocos escuros representam circuitos integrados externos ao FPGA. Os blocos claros, contidos no quadrado pontilhado, são estruturas de hardware dentro do FPGA.
Figura 37 - Diagrama de blocos de uma câmera digital industrial com duas interfaces de saída.
Fonte: Do Autor.
Para realizar o experimento proposto, algumas adaptações foram aplicadas.
Foi dispensado o caminho que leva ao monitor e mantido o caminho que envia para o PC. Além disso a interface Ethernet não está presente no Kit DE10-Lite, sendo necessário substituir por uma UART (Universal Asynchrounous Receiver/Transmiter), que pode ser implementada dentro do FPGA. O diagrama de blocos resultante da adaptação está na Figura 38. Note que o divisor não será utilizado e por consequência apenas um caminho de dados será implementado.
Figura 38 - Arquitetura adaptada para o Kit DE10-Lite.
Fonte: Do Autor.
O bloco “SERIAL-USB” corresponde a um adaptador de uso geral que utiliza o circuito integrado CH340 fabricado pela Nanjing Haoheng Microelectronics Co.
Traduzindo a arquitetura adaptada para a implementação no FPGA, foi utilizada a linguagem de descrição de hardware Verilog e diversas bibliotecas disponíveis na ferramenta de síntese para FPGA Intel (Quartus II - Figura 39).
Figura 39 - Quartus II, a ferramenta de síntese da INTEL.
Fonte: Captura de tela da ferramenta Quartus II.
O primeiro nível na construção da hierarquia é a entidade topo (top-level entity). O projeto de referência do Kit DE10-Lite, fornecido pelo fabricante Terasic, foi utilizado como ponto de partida para aproveitar a declaração de portas e associação de pinos do FPGA. O nome da entidade topo é “DE10_LITE” e seu arquivo correspondente é o “de10_lite.v”. Além das declarações de portas nesta entidade, ainda foi instanciada uma entidade chamada “main_pll” e outra entidade chamada
“camera_soc” (arquivos “main_pll.v” e “camera_soc.v” respectivamente). A Figura 40 ilustra o primeiro nível da arquitetura.
Figura 40 - Entidade topo e suas instâncias.
Fonte: Do Autor.
Na entidade topo foram declaradas as portas de entrada e saída conforme o manual do Kit DE10-Lite, disponibilizado pelo fabricante. Desta forma temos o output ARDUINO_IO_TXD, //////////// gpio //////////
input [11:0] CAMD5M_D,
input CAMD5M_FVAL,
input CAMD5M_LVAL, input CAMD5M_PIXCLK, output CAMD5M_RESET_N, output CAMD5M_SCLK, inout CAMD5M_SDATA, input CAMD5M_STROBE, output CAMD5M_TRIGGER, output CAMD5M_XCLKIN );
Para que haja uma associação física aos pinos do FPGA, é preciso relacionar o nome de cada porta ao respectivo pino. Para fazer isso, a ferramenta Pin Planner auxilia visualmente neste processo. Como exemplo, a Figura 41 mostra a relação entre o sinal CAMD5M_PIXCLK e o pino V10. A ferramenta ainda mostra a posição daquele pino no chip (visão inferior).
Figura 41 - A ferramenta Pin Planner.
Fonte: Adaptado da ferramenta Pin Planner.
A entidade “main_pll” gera diferentes frequências de relógio, a partir de uma fonte de 50 MHz (oscilador do Kit DE10-Lite), para serem utilizadas em outras partes do sistema que serão exploradas adiante. Esta entidade foi gerada automaticamente a partir de parâmetros específicos, com a ferramenta “IP Catalog” (antigamente chamado de MegaWizard) disponível no Quartus II. A Figura 42 mostra a configuração de uma saída de relógio a 25 MHz.
Figura 42 - Configurador de PLL do Quartus II.
Fonte: Adaptado da ferramenta IP Catalog.
A entidade “main_pll” foi instanciada conforme o trecho de código:
main_pll main_pll_inst ( .inclk0 ( MAX10_CLK2_50 ), .areset ( SW[9] ),
.c0 ( c0_100mhz ), .c1 ( c1_50mhz ), .c2 ( c2_25mhz ), .c3 ( c3_1mhz ), );
Já a entidade “camera_soc” representa o coração do sistema. Esta entidade agrega diversos módulos de propriedade intelectual (IP Cores), incluindo o processador Nios II. O “camera_soc” foi instanciado na entidade topo conforme o trecho de código:
camera_soc u0 (
// entradas de clock e reset
.clk_for_100mhz_clk ( c0_100mhz ), .clk_for_50mhz_clk ( c1_50mhz ), .clk_for_25mhz_clk ( c2_25mhz ), .clk_for_1mhz_clk ( c3_1mhz ),
.rst_for_1mhz_reset_n ( reset_active_low ), .rst_for_25mh_reset_n ( reset_active_low ), .rst_for_50mhz_reset_n ( reset_active_low ), .rst_for_100mhz_reset_n ( reset_active_low ), // interface homem máquina
.pio_in_key_export ( pio_key ), .pio_in_switch_export ( pio_switch ), .pio_out_led_export ( pio_led_export ), .pio_in_trigger_in_export ( pio_trigger_in ),
.pio_out_enable_incoming_data_export ( pio_enable_incoming_data), // comunication
.uart4fun_if_tx_led ( ),
.uart4fun_if_tx_bit ( uart_transmitter ), // interface com sensor de imagem
.image_sensor_ctrl_PIXEL_CLK ( CAMD5M_PIXCLK ), .image_sensor_ctrl_LINE_VALID ( CAMD5M_LVAL ), .image_sensor_ctrl_FRAME_VALID ( CAMD5M_FVAL ), .image_sensor_ctrl_PIXEL_DATA ( CAMD5M_D ),
.image_sensor_ctrl_pixel_clk_reset ( pio_enable_incoming_data ),
.image_sensor_cfg_SDAT ( CAMD5M_SDATA ), .image_sensor_cfg_SCLK ( CAMD5M_SCLK ) );
O “camera_soc” foi elaborado na ferramenta Platform Designer, que é mais um recurso integrado ao Quartus II. Para dar uma visão geral da implementação, a Figura 43 mostra parte da tela do Platform Designer com os módulos instanciados.
Figura 43 - Arquitetura da câmera na visão do Intel Platform Designer.
Fonte: Adaptado da ferramenta Platform Designer.
Os itens sinalizados como “grupo 2”, fazem parte da infraestrutura do processador Nios II. Para o correto funcionamento do processador Nios II no sistema, foi adicionado uma memória RAM de 88 kbytes onde vai rodar o software embarcado. Um módulo JTAG (Joint Test Action Group) foi instanciado para permitir a depuração do software em tempo de execução. Diversas portas de entrada e saída (PIO – Parallel I/O) fazem a ligação com chaves e botões do Kit DE10-Lite.
Ainda tem-se outro módulo para interagir com os registradores de configuração do sensor de imagem, através da interface I²C.
Além dos módulos citados, o processador consegue controlar mais três módulos que estão associados ao caminho dos dados. Desta forma pode-se configurar, via software, os endereços de memória para os DMAs (Direct Memory Access) ou acessar diretamente a memória de vídeo. O diagrama de blocos na Figura 44 traduz essa infraestrutura em torno do processador Nios II.
Figura 44 - Diagrama de blocos da infraestrutura montada em torno da CPU Nios II.
Fonte: Do Autor.
Essas ligações entre os módulos obedecem à interface padronizada Avalon Memory Mapped. Este padrão define um conjunto mínimo de sinais para se estabelecer uma transação de escrita ou leitura. Estas transações são comandadas por módulos mestres enquanto os módulos escravos apenas respondem ao que foi solicitado. No diagrama de blocos da Figura 44 apenas o processador Nios II e os dois DMAs são módulos mestres.
Um módulo de memória RAM é do tipo escravo e atende requisições de escrita e leitura. Já um módulo de memória ROM (Read Only Memory), que também é do tipo escravo, só responde às requisições de leituras. O padrão Avalon exige que sempre exista um sinal de relógio e um reset associado.
No módulo escravo, uma transação de leitura precisa ter no mínimo os sinais:
read, address e readData. No módulo mestre, os sinais são: read, waitrequest, address, readDataValid, readData (INTEL, 2019c). Essa diferença entre sinais do módulo mestre e sinais do módulo escravo ocorre pois os módulos não estão conectados diretamente entre si. Existe uma espécie de barramento entre estes módulos, chamado Avalon Fabric, que inclui lógica combinacional e outros circuitos, como os decodificadores de endereços, adaptadores, pipelines, árbitros etc.
O Avalon Fabric é construído automaticamente pela ferramenta Platform Designer, de acordo com as necessidades dos módulos inseridos no sistema. A Figura 45 resume a forma de onda para escrita e leitura do ponto de vista de um módulo master.
Figura 45 - Módulo master no padrão Avalon Memory-Mapped.
Fonte: Adaptado da ferramenta Design Platform.
Voltando à Figura 43, os itens sinalizados como “grupo 3” estão relacionados
ao caminho dos dados (por onde passam os quadros e seus pixels). Estes módulos possuem interface padronizada do tipo Avalon Streaming. Diferente da infraestrutura do processador, estes módulos são ligados ponto-a-ponto e em sequência. Nesse padrão, o fluxo de dados é unidirecional e as interfaces são identificadas como Source e Sink. O módulo com a interface Source é o produtor dos dados, enquanto o módulo com a interface Sink é o consumidor destes dados.
O caminho dos dados inicia-se no decodificador de vídeo, módulo responsável por interpretar os sinais do sensor de imagem e converter para o padrão de sinalização Avalon Streaming. Daí em diante passa por sete módulos (entre adaptadores, conversores e operadores de vídeo) até chegar numa fila (FIFO – First In First Out) utilizada com dois propósitos: dar elasticidade à recepção de dados e conversão do padrão Avalon Streaming para Avalon Memory-Mapped.
O quesito elasticidade resolve situações em que o consumidor está ocupado com outra operação enquanto novas amostras são produzidas e acumuladas. Logo em seguida o consumidor volta esvaziar a fila. No sistema “camera_soc” essa fila está configurada para acumular até 2.048 bytes. Se o produtor acumular mais do que a fila suporta então haverá perda de dados.
O consumidor no sistema é o DMA “alt_incoming_dma”, que possui duas interfaces Avalon Memory-Mapped, sendo que a interface de leitura é responsável por consumir os dados da fila “alt_incoming_fifo”. É importante observar que o sucesso desta abordagem tem relação com a frequência de operação dos dois módulos. O DMA tem o dobro da frequência do módulo que implementa a fila. Desta forma, a fila se mantém vazia a maior parte do tempo. Traduzindo em diagrama de blocos, a Figura 46 mostra o caminho dos dados implementado no Platform Designer.
Figura 46 - Caminho dos dados implementado no Platform Designer.
Fonte: Do Autor.
O padrão Avalon Streaming também determina uma quantidade mínima de sinais entre as interfaces Source-Sink. Nesse modelo não há intervenção do Fabric Avalon, ou seja, os sinais utilizados na interface Source serão os mesmos na interface Sink, porém com direção contrária. Tomando como exemplo os módulos Scaller e Clipper, a interface Source-Sink utiliza os seguintes sinais: ready, valid, startOfPacket, endOfPacket, data, clock e reset (INTEL, 2019c). A Figura 47 resume a forma de onda deste exemplo.
Figura 47 - Exemplo de forma de onda da interface Avalon Streaming.
Fonte: Adaptado da ferramenta Platform Designer.
Finalizando as observações da Figura 43, sobram quatro linhas sinalizadas como “grupo 1” nas quais representam as entradas de relógio para 100 MHz, 50 MHz, 25 MHz e 1 MHz. A quinta coluna da Figura 43 representa as ligações entre relógios e módulos, formando então as árvores de relógio. A convenção aplicada no sistema foi a seguinte:
• No domínio 1 MHz: ficaram os módulos que fazem interface com chaves, botões, leds e número identificador do sistema;
• No domínio 25 MHz: ficaram os módulos de comunicação e adaptadores;
• No domínio 50 MHz: ficaram os módulos que fazem algum processamento no caminho de dados, como o decodificador de imagem e operadores;
• No domínio 100 MHZ: ficaram os módulos DMA, memória e CPU.
No Platform Designer, após todos os módulos estarem configurados e sem nenhuma mensagem de alerta ou erro, é possível compilar a entidade “camera_soc”.
Ao compilar a entidade, a ferramenta gera o código Verilog equivalente. Este procedimento é executado através do botão “Generate HDL”.
Após a geração do código-fonte da entidade “camera_soc”, o Quartus II está pronto para compilar o projeto. Como resultado da compilação do projeto, apenas 16% da capacidade do FPGA foi utilizada, ou seja, consumiu apenas 7.949 Elementos Lógicos. Já o consumo de memória ficou em 75% da capacidade, conforme aponta o relatório de compilação na Figura 48.
Figura 48 - Relatório de compilação do projeto no Quartus II.
Fonte: Adaptado da ferramenta Quartus II.
A compilação gera o bitstream, ou seja, o arquivo binário para configurar o FPGA com o sistema desenvolvido. O bitstream gerado é um arquivo com a extensão “sof” que é um acrônimo para SRAM Object File. Para configurar o FPGA basta chamar a ferramenta Programmer (Figura 49), parte integrante do Quartus II.
Figura 49 - Ferramenta Intel para gravação do bitstream no FPGA.
Fonte: Captura de tela do Quartus II Programmer.
A configuração do FPGA é realizada através de um cabo USB e o gravador embutido no Kit DE10-Lite, chamado USB Blaster. O FPGA MAX10 possui memória Flash interna e permite que o bitstream seja armazenado persistentemente, ou seja, sem a necessidade de realizar o mesmo procedimento ao desligar e ligar o Kit DE10-Lite.