Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa...

80
João Donato da Silva Petroni Interface para processamento de imagens implementada em FPGA São Carlos 2015

Transcript of Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa...

Page 1: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

João Donato da Silva Petroni

Interface para processamento de imagensimplementada em FPGA

São Carlos2015

Page 2: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação
Page 3: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

João Donato da Silva Petroni

Interface para processamento de imagensimplementada em FPGA

Trabalho de Conclusão de Curso apresentado àEscola de Engenharia de São Carlos, da Universidade

de São Paulo

Curso de Engenharia de Computação

ORIENTADOR: Maximiliam Luppe

São Carlos2015

Page 4: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação
Page 5: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação
Page 6: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação
Page 7: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Resumo:

Este trabalho apresenta uma interface para processamento de imagens implementada sobre uma

FPGA e descrita em VHDL que se encarrega de acessar e controlar os hardwares necessários para a

aplicação, como, por exemplo, a entrada de vídeo, a memória RAM e a saída de vídeo. Neste trabalho, o

processamento de imagens é realizado por um hardware externo e dedicado a tarefa, deixando a FPGA

encarregada de acessar e controlar este hardware também.

Palavras-chave: FPGA, VHDL, vídeo, VGA, imagem, processamento de imagem.

7

Page 8: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

8

Page 9: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Abstract:

This paper presents an interface for image processing implemented on an FPGA and described in

VHDL which is responsible for accessing and controlling the hardware required for the application, for

example, the input video, RAM and video output . In this paper, the image processing is performed by an

external hardware and dedicated to the task, leaving responsible for accessing and controlling this hardware

also with the FPGA.

Keywords: FPGA, VHDL, video, VGA, image processing.

9

Page 10: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

10

Page 11: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Sumário

1. Introdução...................................................................................................................................................15

2. Arquitetura do sistema................................................................................................................................17

2.1 Geração dos sinais de relógio..............................................................................................................20

2.2 Entrada de vídeo..................................................................................................................................20

2.3 Processador de imagens.......................................................................................................................21

2.4 Memória de vídeo................................................................................................................................22

2.5 Saída de vídeo......................................................................................................................................25

2.6 Arquitetura final...................................................................................................................................26

3. Implementação............................................................................................................................................29

3.1 Controlador da Entrada de Vídeo.........................................................................................................29

3.2 Controlador de memória RAM estática...............................................................................................30

3.3 Ordenador de operações de memória...................................................................................................32

3.4 Controlador de VGA............................................................................................................................34

3.5 Demais módulos..................................................................................................................................36

3.6 Recursos utilizados..............................................................................................................................36

4. Resultados e Testes.....................................................................................................................................39

4.1 Controlador de VGA............................................................................................................................39

4.2 Controlador e Ordenador de Memória.................................................................................................40

4.3 Repetir Entrada na Saída......................................................................................................................41

5. Conclusão...................................................................................................................................................43

Referências Bibliográficas..............................................................................................................................45

Anexo A: Circuito de entrada de vídeo...........................................................................................................47

Descrição em VHDL do circuito de entrada de vídeo................................................................................47

Diagrama RTL do circuito de entrada de vídeo..........................................................................................50

Anexo B: Circuito controlador de memória RAM..........................................................................................51

Descrição em VHDL do circuito controlador de memória RAM...............................................................51

Diagrama RTL do circuito controlador de memória RAM.........................................................................55

Anexo C: Circuito ordenador de operações de memória.................................................................................57

Descrição em VHDL do circuito ordenador de operações na memória......................................................57

Diagrama RTL do circuito ordenador de operações de memória...............................................................62

Anexo D: Circuito controlador de VGA.........................................................................................................63

Descrição em VHDL do circuito controlador de VGA..............................................................................63

Diagrama RTL do circuito controlador de VGA........................................................................................66

Anexo E: Circuito de teste do controlador de VGA........................................................................................67

Anexo F: Circuito de teste do controlador e ordenador de memória...............................................................69

Anexo G: Circuito de teste de repetição da entrada na saída...........................................................................75

Page 12: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

12

Page 13: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Índice de figuras

Figura 1: Sequência de operações necessárias para a exibição da imagem processada...................................17

Figura 2: Foto do kit de desenvolvimento DE2-70.[1]....................................................................................17

Figura 3: Tela do software Quartus II.[2]........................................................................................................18

Figura 4: ADV7180, CI responsável pela captura de vídeo, em conjunto com a porta de entrada.[4].............19

Figura 5: ADV7123, CI responsável pela conversão digital/analógica, em conjunto com a porta VGA.[4]. . .19

Figura 6: IS61LPS51236A-200TQLI, memória RAM estática.[4].................................................................20

Figura 7: Sinais do padrão ITU-R BT.656. Em que “End of active video” e “Start of active video” são os

marcadores de fim e início de linha, respectivamente, e o intervalo entre estes marcadores são pixeis de

sincronismo.[9]...............................................................................................................................................21

Figura 8: Sinais da memória para uma operação de leitura. Em que “Address” é o endereço em que ocorre a

leitura, “Data out” e “Data in” é o barramento de dados e o restante são os sinais de controle da memória.[6]

........................................................................................................................................................................23

Figura 9: Sinais da memória para uma operação de escrita. Em que “Address” é o endereço em que ocorre a

escrita, “Data out” e “Data in” é o barramento de dados e o restante são os sinais de controle da memória.[6]

........................................................................................................................................................................24

Figura 10: Sinais de sincronismo da VGA. Em que “Display Time” é a área que de fato é exibida, “Blanking

Time” é a área de sincronismo, contendo colunas e linhas de sincronismo,“h_sync signal” é o sinal de

sincronismo de linha e “v_sync signal” é o sinal de sincronismo de quadro.[10]...........................................26

Figura 11: Diagrama do sistema. Blocos em laranja são componentes de hardware do kit, o bloco em verde é

o processador de imagens, os blocos em azul são os módulos descritos em VHDL.......................................27

Figura 12: Interface em VHDL do controlador da entrada de vídeo com uma breve descrição dos sinais de

entrada/saída...................................................................................................................................................29

Figura 13: Interface em VHDL do controlador da memória RAM estática com uma breve descrição dos

sinais de entrada/saída....................................................................................................................................31

Figura 14: Interface em VHDL do ordenador de operações da memória com uma breve descrição dos sinais

de entrada/saída..............................................................................................................................................33

Figura 15: Interface em VHDL do controlador da VGA com uma breve descrição dos sinais de entrada/saída.

........................................................................................................................................................................35

Figura 16: Relatório gerado pelo Quartus II após a compilação completa do sistema....................................37

Figura 17: Frequência máxima que cada sinal de relógio pode gerar sem comprometer o funcionamento do

circuito, cálculo feito pelo Quartus II. Os sinais são, de cima para baixo, o da memória, o da VGA, o gerado

pela entrada de vídeo e o do contador de colunas da VGA.............................................................................37

Figura 18: Padrão de imagem esperado no monitor de vídeo no caso da execução correta do teste...............39

Figura 19: Imagem exibida em um monitor de vídeo como resultado do teste no circuito controlador de

VGA...............................................................................................................................................................40

Figura 20: Imagem exibida em um monitor de vídeo como resultado do teste nos circuitos controlador e

ordenador de memória....................................................................................................................................41

Page 14: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Figura 21: Imagem exibida em um monitor de vídeo como resultado do teste nos circuitos para a repetição de

entrada............................................................................................................................................................42

14

Page 15: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

1. Introdução

Juntamente com a necessidade de se capturar a imagem também é necessário realizar o seu

processamento, podendo ser feito via uma solução por software, executado sobre uma CPU convencional, ou

por hardware, com um circuito projetado para resolver especificamente um problema ou um conjunto de

problemas similares.

Ambas as soluções possuem características favoráveis e contrárias ao seu uso, no caso do software,

pode-se destacar, por exemplo, a facilidade de modificação, permitindo a rápida correção de erros em um

projeto ou a sua adaptação a um problema similar ao que ele foi projetado, e, também, sua independência de

plataforma, podendo ser executado em máquinas diferentes, desde que haja o suporte para isto. Entretanto,

uma solução em software, pode não atender as exigências de performance caso ela seja executada sobre uma

máquina inferior a que ela foi inicialmente planejada e, também, pode apresentar um consumo de potência

acima do desejável para a aplicação.

Uma solução em hardware puramente convencional, por outro lado, possui uma consumo mais

eficiente de potência e, em tese, opera com performance suficiente para atender as necessidades do

problema. Entretanto, sua capacidade de adaptação é reduzida, sendo fixa ao problema que originalmente se

desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a

fabricação do dispositivo.

No contexto dos problemas ocasionados com a escolha de uma solução por hardware, uma medida

para a atenuação de suas características negativas pode ser o uso de uma FPGA (Field Programmable Gate

Array). Esse dispositivo possui a capacidade de implementar uma alta diversidade de circuitos lógicos,

abrangendo uma grande área de aplicação e uma grande facilidade de reconfiguração, permitindo que uma

correção de algum erro no projeto, ou a sua adaptação a um problema similar, se torne mais rápida e menos

custosa. Em contrapartida, o seu uso pode acarretar, no geral, em um consumo de potência mais alto que em

uma solução com hardware puramente convencional.

A FPGA pode, também, assumir um papel de interface com outros hardwares que eventualmente

compõe o sistema. No caso dos sistemas que tratam com imagens capturadas e exibidas, essa característica é

desejável, já que estes sistemas necessitam de uma comunicação tanto entre o componente que captura a

imagem quanto com o que a exibe, sendo que nestas comunicações muitas vezes estão envolvidas

conversões analógico/digital, uso de memória, configuração de dispositivos, etc.

O processamento da imagem capturada pode ser realizado tanto na própria FPGA quanto em um

hardware processador externo, neste último caso, a FPGA atua como apenas como um coordenador entre os

componentes, gerenciando a entrada de vídeo, a memória, a saída de vídeo e este processador. Com esta

solução obtém-se uma maior flexibilidade quanto aos outros componentes utilizados no sistema, sendo

possível alterar alguns deles, como, por exemplo, a entrada de vídeo, e modificar apenas o circuito

incorporado na FPGA que faz o seu controle, permitindo que o hardware de processamento não sofra

modificações para o novo conjunto do sistema.

15

Page 16: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Este trabalho tem como objetivo a construção dessa interface entre um hardware de processamento

de imagens e os demais componentes responsáveis pela captação, exibição e armazenamento da imagem.

Essa interface é construída sobre um kit de desenvolvimento que possui uma FPGA e faz o uso da linguagem

de descrição de hardware VHDL (VHSIC (Very High Speed Integrated Circuit) Hardware Description

Language) para criar os módulos necessários para o controle dos componentes.

No capítulo 2 é apresentado uma descrição geral do sistema, expondo sua arquitetura, o

funcionamento dos hardwares, tanto do processador quanto dos outros componentes do kit, e as soluções

adotadas para se alcançar o objetivo do trabalho.

No capítulo 3 é feita uma descrição mais detalhada sobre o funcionamento dos módulos que realizam

o controle dos componentes, exibindo suas interfaces com os outros módulos e os recursos de lógica que eles

utilizam da FPGA.

No capítulo 4 é demostrado os testes realizados sobre os módulos desenvolvidos, exibindo o seu

funcionamento.

Por fim, no capítulo 5, é feita a conclusão do trabalho.

16

Page 17: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

2. Arquitetura do sistema

O sistema tem o objetivo de servir como uma interface para um processador de imagens. Entretanto,

para se alcançar este objetivo, é necessário acessar um componente para a captação da imagem, armazená-la

em memória, enviá-la para o processador e exibir a imagem processada em uma saída de vídeo, como pode

ser visualizado na figura 1.

A implementação deste sistema é feita sobre o kit de desenvolvimento DE2-70, disponibilizado pela

empresa Terasic, com uma FPGA Cyclone II, da fabricante Altera. Esse kit possui os componentes de

hardware necessários para o funcionamento do sistema, como, por exemplo, um módulo para a aquisição do

vídeo, um componente de memória RAM (Random-access memory) e um conversor digital/analógico para a

saída de vídeo. O kit pode ser visualizado na figura 2.

17

Figura 2: Foto do kit de desenvolvimento DE2-70.[1]

Figura 1: Sequência de operações necessárias para a exibição da imagem processada.

Page 18: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Para realizar o controle dos hardwares são utilizados módulos descritos em VHDL, linguagem

especializada na descrição de circuitos lógicos, isto cria uma maior abstração sobre o projeto dos módulos e

facilita o desenvolvimento de sistemas mais complexos.

Para realizar a conversão do que é descrito pelo VHDL para, de fato, um circuito, é necessário uma

ferramenta de síntese, neste caso, o Quartus II, disponibilizada pela Altera. Além de realizar a síntese da

descrição em VHDL, essa ferramenta possui, também, um ambiente de desenvolvimento para a FPGA, com

a possibilidade de acessar recursos implementados nela e que não são acessíveis puramente via VHDL,

como, por exemplo, circuitos de PLL (Phase-locked loop), úteis para a geração de sinais de relógio. Essa

ferramenta, por fim, também é a responsável pela programação do circuito na FPGA, permitindo o uso, de

fato, do sistema. Uma ilustração do ambiente pode ser vista na figura 3.

Para a captação de imagem é usado o CI (Circuito Integrado) presente no kit, o ADV7180, da

fabricante Analog Devices, este dispositivo permite a captura de vídeo em formatos NTSC (National

Television System Committee), PAL (Phase Alternating Line) e SECAM (Séquentiel couleur à mémoire),

gerando um sinal compatível com o padrão ITU-R BT.656.[3] O CI pode ser visualizado na figura 4.

18

Figura 3: Tela do software Quartus II.[2]

Page 19: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Para a exibição do vídeo, também é usado o CI presente no kit, o ADV7123, também da fabricante

Analog Devices, este dispositivo se encarrega de fazer a conversão de 10 bits por canal de cor, RGB (Red

Green Blue), para uma saída analógica via uma porta VGA (Video Graphics Array).[5] O CI pode ser

visualizado na figura 5.

O armazenamento da imagem é feito por um módulo de memória RAM estática incorporado na

DE2-70, da fabricante ISSI, o IS61LPS51236A-200TQLI, este módulo de memória possui 2Mbytes de

capacidade e opera a uma frequência de 200MHz.[6] O módulo pode ser visualizado na figura 6.

19

Figura 5: ADV7123, CI responsável pela conversão digital/analógica, em conjunto com a porta VGA.[4]

Figura 4: ADV7180, CI responsável pela captura de vídeo, em conjunto com aporta de entrada.[4]

Page 20: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

2.1 Geração dos sinais de relógio

Os sinais de relógio necessários para o funcionamento do sistema são gerados com circuitos de PLL

incorporados na FPGA e acessíveis pela ferramenta Quartus II, a ferramenta permite a configuração deste

circuito baseado em um sinal de relógio existente e das propriedades desejáveis do sinal de relógio

resultante, como, por exemplo, frequência e duty cycle.[7]

O kit de desenvolvimento possui dois sinais de relógio, um de 28,63MHz e outro de 50MHz, com

estes sinais é possível criar um sinal de 25,175MHz, necessário para realizar a interface com a saída VGA

com uma resolução de 640 colunas por 480 linhas a 60 quadros por segundo, e um sinal de 200MHz,

frequência necessária para a operação do módulo de memória RAM.[4][8][6]

2.2 Entrada de vídeo

A entrada do vídeo é realizada via vídeo componente, auxiliada pelo conversor analógico/digital

ADV7180, que recebe os dados de um dispositivo que gera as imagens e as coloca no padrão ITU-R BT.656

para tratamento posterior.[3]

O ITU-R BT.656 descreve a transmissão de pixeis canal por canal, com 8 bits de profundidade cada,

em YCbCr e 4:2:2, isto é, para cada quatro pixeis, são enviados quatro canais de luminância (Y) e dois de

cada canal de crominância (Cb e Cr). Os quadros, neste padrão, são entrelaçados, isto é, transmite-se apenas

as linhas pares e, em seguida, transmite-se apenas as linhas ímpares, estes conjuntos de linhas pares e

ímpares são denominados fields. O padrão também requere pixeis de sincronismo entre linhas e fields, um

diagrama com estes sinais descritos pelo padrão podem ser visualizados na figura 7.[9]

20

Figura 6: IS61LPS51236A-200TQLI, memória RAM estática.[4]

Page 21: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Entretanto, o padrão não determina o comprimento de cada linha, nem a quantidade de linhas de

cada field, deixando esta definição para o formato do vídeo usado, podendo, no caso do ADV7180, ser

NTSC, PAL ou SECAM.[9][3]

O CI incorporado na DE2-70 envia um sinal de relógio com a frequência sincronizada com o

recebimento dos canais, 27MHz, possuindo uma saída com os 8 bits necessários para o envio de cada canal

conforme requerido pelo padrão. Em conjunto com a interface de recepção do vídeo, o CI possui uma

interface i2c responsável por acessar e modificar registradores de controle, estes registradores alteraram o

seu comportamento, podendo, inclusive, realizar operações nos pixeis, como, por exemplo, a aplicação de

correção de gamma, antes de os enviar para a saída.[3]

Um circuito descrito em VHDL recebe os pixeis gerados pelo conversor e os coloca em 4:4:4, isto é,

recuperando para cada pixel todos os seus canais de luminância e crominância. Esse circuito gera, também,

um sinal de relógio com uma subida para cada pixel recebido e já transformado em 4:4:4, aliado a este sinal,

é mantido dois contadores que informam a linha e a coluna, referentes ao field, do pixel que está na saída do

circuito. Por fim, são mantidos um sinal informando se o field atual é composto por linhas pares ou ímpares e

um outro sinal informando se o vídeo está na região ativa, isto é, recebendo valores de pixeis válidos, ou se

está em uma região de sincronismo.

2.3 Processador de imagens

O processador de imagens é um hardware que recebe os pixeis da entrada de vídeo e realiza alguma

operação sobre eles, enviando a resposta para a saída de vídeo, este hardware pode ser implementado na

própria FPGA ou externamente.

Neste sistema, o processador de imagens é um hardware externo a FPGA e conectado ao kit de

desenvolvimento, possuindo entradas para um sinal de relógio, um sinal de enable, um sinal de reset, uma

entrada para receber os pixeis a serem processados e uma saída para enviar os pixeis já modificados. Esse

21

Figura 7: Sinais do padrão ITU-R BT.656. Em que “End of active video” e “Start of active video” são os marcadores de fim e início de linha, respectivamente, e o intervalo entre estes marcadores são pixeis de sincronismo.[9]

Page 22: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

processador é um trabalho independente a este, sendo que o sistema abordado neste trabalho atua,

principalmente, como suporte para o funcionamento desse processador.

A operação que o processador realiza é a transformada de distância, necessitando apenas de uma

imagem binária contendo a borda dos objetos como entrada. Portanto, ele recebe apenas um bit por pixel,

logo, antes de se enviar um pixel ao processador, ele passa por um processo de binarização, tal processo

considera o canal de luminância do pixel, sendo admitido “1” caso o valor deste canal seja mais próximo ao

branco do que o cinza de intensidade intermediária e “0” caso contrário. O processador gera como saída uma

imagem em tons de cinza, levando N x M ciclos de relógio para processar a imagem completa, sendo N e M

a largura e altura da imagem, respectivamente.

Para realizar a interface com este processador, um circuito descrito em VHDL se encarrega de

receber o pixel e realizar o processo de binarização, enquanto que um circuito adaptador, também em VHDL,

se encarrega de ajustar os sinais de controle da memória, isto é, o endereço do pixel, até o processador estar

apito a recebê-lo.

2.4 Memória de vídeo

Devido as diferenças na velocidade do processamento da entrada de vídeo e da saída, é necessário

armazenar cada quadro do vídeo antes de exibi-lo, evitando que a imagem final esteja corrompida. Esse

armazenamento é feito com o módulo de memória RAM estática presente no kit de desenvolvimento.

O módulo de memória opera com um sinal de relógio de 200MHz, com tamanho de palavra de 36

bits – 4 bytes mais 4 bits de paridade – com 512k posições. As operações de escrita e leitura ocupam 2 e 3

ciclos de relógio, respectivamente, sendo que a operação de escrita permite a seleção dos bytes, entre os 4 do

tamanho da palavra, que se deseja armazenar. A memória apresenta, ainda, um modo de operação em burst,

em que as operações são feitas em posições consecutivas e em ciclos de relógio consecutivos, sendo

necessário aguardar todos os ciclos da operação apenas na operação em que se define a posição inicial.[6]

Os três ciclos de operação da leitura estão divididos entre: o endereçamento, um ciclo de espera e a

recuperação dos dados. No ciclo de endereçamento, é definida a posição que se quer recuperar os dados

armazenados, no ciclo de espera, apenas se habilita a saída da memória e, por fim, no ciclo de recuperação de

dados, os dados estão prontos para serem lidos do barramento.[6] Um diagrama com o sinais de controle da

memória pode ser visualizado na figura 8.

22

Page 23: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Os ciclos da operação de escrita são divididos entre: endereçamento e armazenamento de dados. No

ciclo de endereçamento, é definida a posição que se quer escrever e no ciclo de armazenamento é definido

quais bytes são escritos e quais os valores destes bytes.[6] Um diagrama com o sinais de controle da memória

pode ser visualizado na figura 9.

23

Figura 8: Sinais da memória para uma operação de leitura. Em que “Address” é o endereço em que ocorre a leitura, “Data out” e “Data in” é o barramento de dados e o restante são os sinais de controle da memória.[6]

Page 24: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

O acesso a memória é feito via um circuito descrito em VHDL que se encarrega de receber a

operação desejada, ajustar os sinais de controle da memória e aguardar os ciclos necessários para o término

da operação. Esse módulo sempre lê e escreve palavras inteiras, isto é, 32 bits, se desconsiderados os bits de

paridade. O módulo, também, envia um sinal indicando a sua disponibilidade de realizar operações, mantido

em nível lógico alto quando estiver disponível, e um outro sinal para quando um dado está pronto para ser

lido, também mantido em nível lógico alto quando disponível.

O comportamento do circuito de acesso a memória é obtido via uma máquina de estados, que se

encarrega de manter a ordem sobre as etapas de cada operação a ser realizada. Essa máquina possui cinco

24

Figura 9: Sinais da memória para uma operação de escrita. Em que “Address” é o endereço em que ocorre a escrita, “Data out” e “Data in” é o barramento de dados e o restante são os sinais de controle da memória.[6]

Page 25: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

estados, um de espera, em que não é realizada nenhuma operação, 3 estados de leitura, um referente a cada

etapa da operação de leitura descrita anteriormente, e 2 estados de escrita, também referentes as etapas da

operação de escrita.

Entretanto, como no sistema ocorre a captação e exibição de dados simultaneamente, é necessário

um módulo que ordene as operações enviadas para o controlador de memória RAM, este módulo possuiu um

sinal de relógio para a operação de escrita e um para a leitura, supondo que estes sinais sejam

consideravelmente mais lentos que o sinal de relógio que alimenta a memória de fato, é possível realizar

operações de escrita e leitura aparentemente simultâneas. Os sinais de relógio da operação de leitura e o da

operação de escrita estão limitados pelos sinais da VGA, em 25,175Mhz, necessário para se manter a

resolução do vídeo do vídeo em 640 colunas por 480 linhas a 60 quadros por segundo, e o gerado pela

entrada de vídeo, por padrão, em 27MHz, enquanto o sinal da memória está em 200MHz, portanto, a

suposição anterior, de que os sinais da escrita e de leitura sejam mais lentos que o da memória é factível.[8]

[3][6]

Esse módulo, também possui, duas entradas para escrita, permitindo que duas operações

independentes sejam executadas sequencialmente, facilitando um processo de desentrelaçamento em que um

mesmo pixel é escrito em duas linhas consecutivas do vídeo.

O comportamento desse módulo também é obtido via uma máquina de estados, com 4 estados, um

de espera, em que nenhuma operação é realizada, um de leitura, em que é aguardado o término da operação

de leitura e dois de escrita, cada um associado a uma entrada, em que é aguardado o termino das operações

de escrita.

2.5 Saída de vídeo

A saída de vídeo é feita por uma interface VGA, com uma resolução de 640 colunas por 480 linhas e

quadros a 60Hz, neste tipo de interface, a imagem é envida serialmente da esquerda para a direita e de cima

para baixo, enviando todas as colunas de uma linha antes de se enviar outra.[10]

Entretanto, para o funcionamento correto da interface, é necessário que se inclua sinais de

sincronismo em que, ao final e começo de cada linha, colunas de sincronismo são inseridas e, ao final e

começo de cada quadro, linhas de sincronismo são inseridas. Juntamente com essas linhas e colunas, ainda é

necessário mais um sinal indicando o sincronismo de linha e outro indicando o sincronismo de quadro.[10]

Estes sinais de sincronismo podem ser visualizados na figura 10.

25

Page 26: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

O controle destes sinais é feito por um módulo descrito em VHDL que possui dois contadores, um

para as colunas, incluindo as colunas de sincronismo, e um para as linhas, também incluindo as linhas de

sincronismo. Desta forma, o controlador é capaz de emitir sinais quando a VGA se encontra no estado de

sincronismo e, também, informar a coluna e a linha que se está enviando no momento.

Com o valor das colunas e das linhas geradas pelo módulo controlador da VGA, é possível acessar a

posição de memória que representa o pixel a ser exibido, permitindo a recuperação desse pixel, o passando

pelo processador e, em seguida, ao CI do kit responsável pela conversão digital/analógica.

2.6 Arquitetura final

A arquitetura final do sistema, com os componentes de hardware necessários, o processador de

imagens e os módulos em VHDL, pode ser visualizada na figura 11.

26

Figura 10: Sinais de sincronismo da VGA. Em que “Display Time” é a área que de fato é exibida, “Blanking Time” é a área de sincronismo, contendo colunas e linhas de sincronismo,“h_sync signal” é o sinal de sincronismo de linha e “v_sync signal” é o sinal desincronismo de quadro.[10]

Page 27: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Na próxima seção, é mostrado com mais detalhes a implementação desses módulos descritos em

VHDL, informando os seus sinais de entrada e de saída, juntamente com a sua lógica.

27

Figura 11: Diagrama do sistema. Blocos em laranja são componentes de hardware do kit, o bloco em verde é o processador de imagens, os blocos em azul são os módulos descritos em VHDL.

Page 28: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

28

Page 29: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

3. Implementação

Nesta seção são apresentados o funcionamento interno dos módulos implementados em VHDL

mencionados na seção anterior, exibindo as suas interfaces, descrevendo os seus comportamentos e exibindo

diagramas que representam as suas lógicas de funcionamento.

3.1 Controlador da Entrada de Vídeo

A interface descrita em VHDL do módulo que recebe os pixeis via o ADV7180 pode ser visualizada

na figura 12.

29

entity VideoInputController is generic ( busSize : natural := 8; -- Tamanho do barramento. hRes : natural := 640; -- Resolução horizontal máxima do vídeo. vRes : natural := 480 -- Resolução vertical máxima do vídeo. ); port ( clock : in std_logic; -- Sinal de relógio recebido do ADV7180. enable : in std_logic; -- Habilita o circuito. reset : in std_logic; -- Reinicia o circuito.

-- Dados gerados pelo ADV7180. dataIn : in std_logic_vector(busSize - 1 downTo 0);

-- Canal Y de saída. outY : out std_logic_vector(busSize - 1 downTo 0); -- Canal Cb de saída. outCb : out std_logic_vector(busSize - 1 downTo 0); -- Canal Cr de saída. outCr : out std_logic_vector(busSize - 1 downTo 0);

-- Mantido em '1' quando há um pixel válido, '0' caso contrário. activeVideo : out std_logic;

-- Informa o field do pixel atual. field : out std_logic; -- Contador de linhas. row : out std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); -- Contador de colunas. col : out std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );

-- Gera uma subida quando um pixel pode ser lido da saída. clockPixel : out std_logic; -- Gera uma subida quando o valor do contador de linhas mudar. clockLine : out std_logic; -- Gera uma subida quando o field mudar. clockField : out std_logic ); end VideoInputController;

Figura 12: Interface em VHDL do controlador da entrada de vídeo com uma breve descrição dos sinais de entrada/saída.

Page 30: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Os parâmetros recebidos pelo módulo, isto é, os que estão contidos na seção generic da interface

exibida na figura 12, representam a resolução do vídeo a ser exibido (hRes e vRes) e o tamanho do

barramento de dados (busSize) que é usado para receber cada canal, neste caso, 8 bits.

O sinal de relógio é gerado pelo próprio ADV7180 e é utilizado para controlar uma máquina de

estados que se encarrega de ordenar os dados recebidos e verificar se eles são de sincronismo ou de algum

canal válido. Caso esses dados sejam de um canal válido, o sinal activeVideo é mantido em nível lógico alto

e uma borda de subida é gerada no sinal clockPixel quando as saídas outY, outCb e outCr estiverem com um

pixel novo e válido. Entretanto, se os dados forem de sincronismo, o sinal activeVideo é mantido em nível

lógico baixo, indicando que as saídas produzidas são inválidas.

Quando há a detecção da entrada na região de sincronismo, uma borda de subida é gerada no sinal

clockLine, indicando um fim de linha e, caso seja percebido uma mudança de field, uma borda de subida é

gerada no sinal clockField, e é alterado o valor do sinal field. A detecção do fim de linha e do fim de field é

feita conforme o descrito pelo padrão ITU-R BT.656.[9]

Os sinais col e row indicam a coluna e a linha, respectivamente, que o módulo está enviando no

momento. O contador de coluna é incrementado a cada pixel e é reiniciado a cada fim de linha, enquanto o

contador de linha é incrementado a cada fim de linha e é reiniciado a cada fim de field.

O código completo do componente juntamente com um diagrama RTL (Register Transfer Level) do

módulo, gerado pelo Quartus II na compilação do código, podem ser visualizados no anexo A.

3.2 Controlador de memória RAM estática

A interface descrita em VHDL do módulo que controla a memória RAM estática pode ser

visualizada na figura 13.

30

Page 31: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

O sinal de relógio deste módulo é o mesmo da memória, sendo que ele é usado para alimentar a

máquina de estados que se encarrega de controlar os ciclos das operações. A máquina, ao finalizar uma

operação, coloca a sinal nextOp em nível lógico alto e, se no próximo ciclo do sinal de relógio, o sinal de

31

entity memorySSRam is port ( -- Sinal de relógio de 200 MHz. clock : in std_logic; -- Habilita o circuito para realizar uma operação. enable : in std_logic; -- Operação: '1' leitura, '0' escrita. op : in std_logic;

-- Endereço. address : in std_logic_vector( 18 downTo 0 ); -- Entrada de dados (escrita). dataIn : in std_logic_vector( 31 downTo 0 ); -- Saídas de dados (leitura). dataOut : out std_logic_vector( 31 downTo 0 );

-- Em '1' indica a disponibilidade de realizar uma operação. nextOp : out std_logic;

-- Indica que o dado na saída de dados é válido. dataValid : out std_logic;

-- Comunicação com a memória (ativos em '0'): memoryCE : out std_logic; -- Chip Enable. memoryCE2 : out std_logic; -- Chip Enable 2 (ativo em '1'). memoryCE2n : out std_logic; -- /Chip Enable 2. memoryADV : out std_logic; -- Burst address advance. memoryADSP : out std_logic; -- Address status processor. memoryADSC : out std_logic; -- Address status cache controller.

memoryGW : out std_logic; -- Global write. memoryOE : out std_logic; -- Output enable.

memoryBWE : out std_logic; -- Byte write enable. memoryBWa : out std_logic; -- Byte write A. memoryBWb : out std_logic; -- Byte write B. memoryBWc : out std_logic; -- Byte write C. memoryBWd : out std_logic; -- Byte write D. -- Endereço (enviado para a memória). memoryAddress : out std_logic_vector( 18 downTo 0 );

-- Bits de paridade. memoryDataParity : inout std_logic_vector( 3 downTo 0 );

--Barramento de dados. memoryData : inout std_logic_vector( 31 downTo 0 ) ); end memorySSRam;

Figura 13: Interface em VHDL do controlador da memória RAM estática com uma breve descrição dos sinais de entrada/saída.

Page 32: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

enable estiver, também, em nível lógico alto, uma nova operação é realizada. Essa operação é indicada pelo

sinal op, que faz com que a máquina siga o ciclo da operação desejada. Entretanto, caso o sinal enable

estiver em nível lógico baixo, a máquina entra em estado de espera, aguardando até que o este sinal seja

ativado.

O sinal address indica em que endereço de memória a operação deve ser realizada, o sinal dataIn

recebe os dados que devem ser armazenados na memória em uma operação de escrita, enquanto que o sinal

dataOut informa os dados recebidos por uma operação de leitura, juntamente a este sinal, o sinal dataValid é

mantido em nível alto quando o dado da saída é valido.

Os demais sinais são referentes aos sinais de controle do próprio CI de memória RAM estática e são

projetados para serem conectados diretamente com as portas da memória.

O código completo do componente juntamente com um diagrama RTL do módulo, gerado pelo

Quartus II na compilação do código, podem ser visualizados no anexo B.

3.3 Ordenador de operações de memória.

A interface descrita em VHDL do módulo que ordena as operações sobre a memória RAM pode ser

visualizada na figura 14.

32

Page 33: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Os parâmetros addressBusSize e dataBusSize indicam o tamanho, em bits, do barramento de

endereços e de dados, respectivamente. Os valores desses parâmetros estão vinculados aos barramentos da

memória RAM que, neste caso, são de 19 e 32, respectivamente.

As operações são habilitadas via os sinais readEnable, writeEnableA e writeEnableB em nível lógico

alto, estes sinais estão associados a operação de leitura e a duas operações de escrita, respectivamente. As

duas operações de escritas são nomeadas A e B, sendo que todos os sinais referentes a escrita e terminados

em A são relacionados a operação de escrita A e todos terminados em B são relacionados a operação B.

O sinal de relógio principal, clock, é idêntico ao da memória, 200MHz, e é o sinal que regula a

máquina de estados interna que ordena as operações. Os sinais clockRead e clockWrite estão associados a

requisição de operações de leitura e escrita, respectivamente. Portanto, ao se receber uma borda de subida em

algum destes sinais e algum dos sinais responsáveis pela habilitação da operação estiver ativo, a operação

33

entity memoryDualPort is generic ( addressBusSize : natural := 19; -- Tamanho do barramento de endereço. dataBusSize : natural := 32 -- Tamanho do barramento de dados. ); port ( clock : in std_logic; -- Sinal de relógio da memória (~200MHz). clockRead : in std_logic; -- Sinal de relógio da leitura. clockWrite : in std_logic; -- Sinal de relógio da escrita. opEnable : in std_logic; -- Habilita a realização de operações. readEnable : in std_logic; -- Habilita a operação de leitura. writeEnableA : in std_logic; -- Habilita a operação de escrita A. writeEnableB : in std_logic; -- Habilita a operação de escrita B.

-- Endereço de leitura. addressRead : in std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereço de escrita A. addressWriteA : in std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereço de escrita B. addressWriteB : in std_logic_vector( addressBusSize - 1 downTo 0 );

-- Dados escritos pela operação A. dataInA : in std_logic_vector( dataBusSize - 1 downTo 0 ); -- Dados escritos pela operação B. dataInB : in std_logic_vector( dataBusSize - 1 downTo 0 ); -- Interface com o controlador de memória. memoryEnable : out std_logic; -- Habilita o controlador. memoryOp : out std_logic; -- Operação: '1' leitura, '0' escrita. -- Endereço da operação. memoryAddress : out std_logic_vector( addressBusSize - 1 downTo 0 ); -- Dados a serem escritos. memoryDataWrite : out std_logic_vector( dataBusSize - 1 downTo 0 ) ); end memoryDualPort;

Figura 14: Interface em VHDL do ordenador de operações da memória com uma breve descrição dos sinaisde entrada/saída.

Page 34: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

requerida é marcada para ser executada.

Os sinais addressRead, addressWriteA e addressWriteB são os endereços de memória que as

operações de leitura e as duas de escritas devem ocorrer, respectivamente. No caso das operações de escrita,

os dados que são escritos são os dos sinais dataInA e dataInB.

O sinal opEnable em '1' indica a disponibilidade do controlador de memória de receber mais uma

operação, este sinal é projetado para ser conectado ao sinal nextOp do controlador de memória RAM. Algo

similar ocorre com os demais sinais desse módulo: memoryEnable, memoryOp, memoryAddress e

memoryDataWrite, que são sinais para se conectarem aos sinais enable, op, address e dataIn, do módulo

controlador de memória, respectivamente.

O código completo do componente juntamente com um diagrama RTL do módulo, gerado pelo

Quartus II na compilação do código, podem ser visualizados no anexo C.

3.4 Controlador de VGA

A interface descrita em VHDL do módulo que controla a VGA pode ser visualizada na figura 15.

34

Page 35: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Os parâmetros recebidos pelo controlador representam a resolução do vídeo a ser exibido (hRes e

vRes) e a quantidade de colunas e linhas necessárias para realizar o sincronismo (os demais parâmetros),

estes parâmetros influenciam na frequência que o sinal de relógio deve possuir para que ocorra o envio

correto dos pixeis, que, neste caso, é de 25,175Mhz. [8]

Os sinais col e row indicam a coluna e a linha, respectivamente, que o controlador espera que se

envie no momento. O contador de coluna é incrementado a cada pixel e é reiniciado a cada fim de linha,

enquanto o contador de linha é incrementado a cada vez que o contador de colunas é reiniciado e é reiniciado

a cada fim de quadro, gerando uma borda de subida no sinal clockFrame.

Os sinais hBlank e vBlank apenas indicam se o pixel enviado é de sincronismo ou pertence a imagem

de fato. Por fim, os sinais hSync e vSync são responsáveis pelos pulsos de sincronismo horizontal e vertical,

respectivamente, conforme a figura 10.

O código completo do componente juntamente com um diagrama RTL (Register Transfer Level) do

35

entity VGAController is generic( hRes : natural := 640; -- Resolução horizontal do vídeo. vRes : natural := 480; -- Resolução vertical do vídeo.

hFrontPorch : natural := 16; -- 'Pixeis' do 'FrontPorch' horizontal. hSyncPulse : natural := 96; -- 'Pixeis' do 'SyncPulse' horizontal. hBackPorch : natural := 48; -- 'Pixeis' do 'FrontPorch' horizontal.

vFrontPorch : natural := 10; -- 'Linhas' do 'FrontPorch' vertical. vSyncPulse : natural := 2; -- 'Linhas' do 'SyncPulse' vertical. vBackPorch : natural := 33 -- 'Linhas' do 'FrontPorch' vertical. );

port ( clock : in std_logic; -- Sinal de relógio do pixel. enable : in std_logic; -- Habilita o circuito. reset : in std_logic; -- Reinicia o circuito.

-- Linha do pixel row : out std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); -- Coluna do pixel col : out std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );

hBlank : out std_logic; -- '1' se em sincronismo horizontal. vBlank : out std_logic; -- '1' se em sincronismo de quadro.

hSync : out std_logic; -- Pulso hsync. vSync : out std_logic; -- Pulso vsync.

-- Gera uma subida quando um quadro acabar. clockFrame : out std_logic );

end VGAController;

Figura 15: Interface em VHDL do controlador da VGA com uma breve descrição dos sinais de entrada/saída.

Page 36: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

módulo, gerado pelo Quartus II na compilação do código, podem ser visualizados no anexo D.

3.5 Demais módulos

Há, ainda, os outros módulos necessários para deixar o sistema funcional, entre eles, pode-se citar, os

módulos associados com a interface com o processador de imagens, isto é, o módulo responsável pela

binarização do pixel e o responsável pela adaptação dos sinais de controle da memória, e, também, os

módulos responsáveis pela geração dos sinais de relógio.

Estes outros módulos possuem um funcionamento mais simples que os demais, o módulo de

binarização, por exemplo, é composto apenas por um barramento de entrada, um bit de saída e uma

comparação do valor de entrada a um limiar previamente definido, deixando a saída em nível lógico alto

caso a comparação seja verdadeira ou em nível lógico baixo caso seja falsa. O módulo de adaptação dos

sinais é composto basicamente por flip-flops, responsáveis por reter os sinais de controle quando necessário.

Os módulos para a geração dos sinais de relógio são, como já descrito, criados com o auxílio da

ferramenta Quartus II, sendo que esta ferramenta disponibiliza, apenas, uma interface para cada módulo

criado, contendo um sinal de relógio de entrada, que deve ser um dos dois disponíveis pelo kit, e um sinal de

saída, com as propriedades requiridas ao se configurar o módulo. Entretanto, o funcionamento interno destes

módulos é desconhecido, uma vez que apenas é exposta a interface do módulo e não a sua descrição

completa.

Por fim, um último módulo é responsável por agregar todos os outros módulos, conectando os sinais

que cada módulo recebe e gera, fazendo eventuais operações para adaptar os sinais entre os módulos e os

conectando as portas físicas da FPGA.

3.6 Recursos utilizados

O sistema, considerando todos os seus módulos, consome 370 elementos lógicos, com 148 pinos e

usando 2 dos 4 PLLs disponíveis na FPGA. Esses dados e outros mais podem ser visualizados no relatório

gerado pelo Quartus II após a compilação completa do sistema, que é exibido na figura 16.

36

Page 37: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Juntamente com o relatório, é possível se obter a frequência máxima comportada por cada sinal de

relógio disponível no sistema sem que se comprometa o funcionamento dos circuitos, esta informação pode

ser visualizada na figura 17.

37

Figura 16: Relatório gerado pelo Quartus II após a compilação completa do sistema.

Figura 17: Frequência máxima que cada sinal de relógio pode gerar sem comprometer o funcionamento do circuito, cálculo feito pelo Quartus II. Os sinais são, de cima para baixo, o da memória, o da VGA, o geradopela entrada de vídeo e o do contador de colunas da VGA.

Page 38: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

38

Page 39: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

4. Resultados e Testes

Para verificar o funcionamento dos circuitos é criado um padrão de imagem implementado no

próprio circuito de teste que, no caso do funcionamento correto, é exibido em um monitor de vídeo, este

padrão pode ser visualizado na figura 18.

Esse padrão é utilizado em todos os três testes realizados, o do controlador de VGA, o do controlador

e ordenador de memória e a repetição da entrada na saída.

4.1 Controlador de VGA

Neste teste é verificado apenas o comportamento do controlador de VGA. O teste é gerado pelo

código em VHDL exibido no anexo E.

A geração do padrão de teste, neste caso, é feita via uma lógica ligada diretamente na saída da VGA,

colocando todos os canais de saída em nível lógico alto, gerando o branco, ou em nível lógico baixo, gerando

o preto, conforme os contadores do controlador. Como resultado se obtém em um monitor de vídeo a

imagem da figura 19.

39

Figura 18: Padrão de imagem esperado no monitor de vídeo no caso da execução correta do teste.

Page 40: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

O resultado obtido na figura 19 é similar ao padrão de referência representado na figura 18, podendo-

se supor, portanto, que o circuito controlador de VGA está com o seu funcionamento adequado.

4.2 Controlador e Ordenador de Memória

Neste teste é verificado o funcionamento dos circuitos de controle da memória RAM e o ordenador

de operações, com o uso do controlador de VGA para a exibição do resultado no monitor. O teste é gerado

pelo código em VHDL exibido no anexo F.

A geração do padrão de teste é similar a descrita no teste anterior, fazendo uso de contadores para

decidir se é uma região de cor branca (nível lógico alto) ou preta (nível lógico baixo). Entretanto, ao invés de

ser ligado diretamente na saída de vídeo, o padrão é escrito na memória, fazendo uso do controlador e do

ordenador de operações. Juntamente com a escrita, é realizada a leitura, enviando os dados recebidos para a

saída de vídeo. Desta forma é testada a capacidade de leitura e escrita da memória juntamente com a

capacidade de ordenar o acesso a ela.

Como saída se obtém a imagem da figura 20.

40

Figura 19: Imagem exibida em um monitor de vídeo como resultado do teste no circuito controlador de VGA.

Page 41: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Novamente, o resultado obtido na figura 20 é similar ao representado no padrão de referência da

figura 18, podendo-se supor, portanto, que o circuito ordenador de operações e o controlador de memória

RAM estão com os seus funcionamentos adequados.

4.3 Repetir Entrada na Saída

Neste teste é verificado a capacidade do sistema de repetir uma imagem da entrada de vídeo e exibi-

la em um monitor de vídeo. Esse é o teste mais abrangente do sistema, passando pelos circuitos de entrada de

vídeo, de ordenação e controle de memória e o controle de VGA. O teste é gerado pelo código em VHDL

exibido no anexo G.

O padrão é gerado por uma imagem salva em uma câmera fotográfica que é ligada a entrada de vídeo

do kit. A entrada é tratada pelo circuito controlador da entrada de vídeo e armazenada na memória, fazendo

uso do ordenador e controlador de memória, por fim, é feita a leitura da memória e o envio para a saída de

vídeo.

Como saída se obtém a imagem da figura 21.

41

Figura 20: Imagem exibida em um monitor de vídeo como resultado do teste nos circuitos controlador e ordenador de memória.

Page 42: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Como observado na figura 21, o teste não foi bem sucedido, já que o padrão esperado não se repetiu

na tela do monitor de vídeo. Entretanto, como nos outros testes descritos ocorreu a correta exibição do

padrão no vídeo, pode-se supor, por este último teste, que o circuito com comportamento incorreto seja o

controlador da entrada de vídeo.

42

Figura 21: Imagem exibida em um monitor de vídeo como resultado do teste nos circuitos para a repetição de entrada.

Page 43: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

5. Conclusão

Este trabalho demostra a criação de um sistema para a interface com um processador de imagens em

um kit com uma FPGA, descrevendo os componentes de hardware utilizados do kit, juntamente com os

módulos em VHDL necessários para se fazer o controle destes componentes.

Os resultados obtidos com o projeto, entretanto, não são suficientes para o funcionamento completo

do sistema, já que em um dos testes não é apresentado o comportamento esperado. Apesar desse fato, eles

demostram a capacidade que a FPGA tem de receber a lógica descrita em VHDL e realizar o controle dos

componentes do kit, como se mostra nos testes com os módulos de controle de VGA e de controle da

memória RAM. Isso vai de encontro a proposta que a FPGA possui de ser flexível ao tipo de aplicação que

se quer desenvolver, permitindo uma rápida modificação da lógica implementada.

Ainda com relação aos resultados, mesmo não contemplando toda a funcionalidade do sistema, é

possível de se fazer uma suposição dos módulos que estão com o comportamento incorreto, já que pela

forma como os testes se dão, o erro ocorre quando o módulo de controle da entrada de vídeo é acionado,

levantando a suspeita sobre este módulo.

Uma característica que se nota ao decorrer do desenvolvimento do projeto, envolvendo a linguagem

VHDL e a FPGA, é a possibilidade de se descrever um circuito que é sintetizável, que pode possuir um

comportamento correto em simulações, mas que ao se implementar na FPGA é obtido um funcionamento

incorreto. Esse fato decorre, principalmente, de peculiaridades do funcionamento da FPGA. A fabricante,

para tentar amenizar o problema, disponibiliza uma guia de boas práticas sobre como deve ser o

comportamento dos circuitos lógicos implementados sobre as suas FPGAs.[11]

Como sugestões para eventuais futuros trabalhos ficam a correção do módulo de controle da entrada

de vídeo e outras eventuais adaptações, como, por exemplo, a construção de um módulo mestre i2c para

configurar mais precisamente o CI responsável pela conversão analógica/digital da entrada de vídeo.

43

Page 44: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

44

Page 45: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Referências Bibliográficas

1 DE2-70 Development and Education Board. Disponível em:

http://www.altera.com/education/univ/materials/boards/de2-70/unv-de2-70-board.html Acesso em 28

Out. 2014

2 Getting started - an introduction to Quartus. Disponível em:

http://www.cl.cam.ac.uk/teaching/0910/ECAD+Arch/lab1/gettingstarted.html Acesso em 28 Out. 2014

3 ADV7180: 10-Bit, 4x Oversampling SDTV Video Decoder Data Sheet (Rev I, 02/2014) .

http://www.analog.com/static/imported-files/data_sheets/ADV7180.pdf Acesso em 28 Out. 2014

4 DE2-70 User Manual. Disponível em: ftp://ftp.altera.com/up/pub/Altera_Material/12.1/Boards/DE2-

70/DE2_70_User_Manual.pdf Acesso em 28 Out. 2014

5 ADV7123: CMOS, 330 MHz Triple 10-Bit High Speed Video DAC Data Sheet (Rev D, 07/2010) .

http://www.analog.com/static/imported-files/data_sheets/ADV7123.pdf Acesso em 28 Out. 2014

6 18Mb Synchronous Pipelined,Single Cycle Deselect Static Ram.

http://www.issi.com/WW/pdf/61VPS_LPS-51236A_102418A.pdf Acesso em 28 Out. 2014

7 ALTPLL (Phase-Locked Loop) IP Core User Guide. Disponível em:

http://www.altera.com/literature/ug/ug_altpll.pdf Acesso em 28 Out. 2014

8 VGA Signal 640 x 480 @ 60 Hz Industry standard timing. Disponível em: http://tinyvga.com/vga-

timing/640x480@60Hz Acesso em 28 Out. 2014

9 ITU-R BT.656. Disponível em: http://www.itu.int/rec/R-REC-BT.656-5-200712-I/en Acesso em 28 Out.

2014

10 VGA Controller (VHDL). Disponível em: https://eewiki.net/pages/viewpage.action?pageId=15925278

Acesso em 28 Out. 2014

11 Recommended Design Practices. Disponível em:

http://www.altera.com/literature/hb/qts/qts_qii51006.pdf Acesso em 28 Out. 2014

45

Page 46: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

46

Page 47: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo A: Circuito de entrada de vídeo.

Descrição em VHDL do circuito de entrada de vídeo.

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;

library util;use util.bits.all;

entity VideoInputController is generic ( busSize : natural := 8; -- Tamanho do barramento. hRes : natural := 640; -- Resolução horizontal máxima do vídeo. vRes : natural := 480 -- Resolução vertical máxima do vídeo. ); port ( clock : in std_logic; -- Sinal de relógio recebido do ADV7180. enable : in std_logic; -- Habilita o circuito. reset : in std_logic; -- Reinicia o circuito.

dataIn : in std_logic_vector(busSize - 1 downTo 0); -- Dados gerados pelo ADV7180.

outY : out std_logic_vector(busSize - 1 downTo 0); -- Canal Y de saída. outCb : out std_logic_vector(busSize - 1 downTo 0); -- Canal Cb de saída. outCr : out std_logic_vector(busSize - 1 downTo 0); -- Canal Cr de saída.

field : out std_logic; -- Informa o field do pixel atual. activeVideo : out std_logic; -- Mantido em '1' quando há um pixel válido, '0' caso contrário. row : out std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); -- Contadorde linhas. col : out std_logic_vector( nBits(hRes - 1) - 1 downTo 0 ); -- Contadorde colunas.

clockPixel : out std_logic; -- Gera uma subida quando um pixel pode ser lido da saída. clockLine : out std_logic; -- Gera uma subida quando o valor do contador de linhas mudar. clockField : out std_logic -- Gera uma subida quando o field mudar. );end VideoInputController;

architecture behaviour of VideoInputController is -- Padrão ITU. Palavra que indica o início de um bloco de sincronismo. constant SYNC_START : std_logic_vector(busSize - 1 downTo 0) := (others => '1'); -- Padrão ITU. Bit que indica se é um eav (1) ou um sav (0). constant EAV_SAV_BIT : natural := busSize - 4; -- Padrão ITU. Bit que indica se está em blank ou não. constant BLANK_BIT : natural := busSize - 3; -- Padrão ITU. Bit que indica o field atual. constant FIELD_BIT : natural := busSize - 2;

-- Máquina de estados: -- blank: Em sincronismo. -- Y1: Canal de luminância do pixel.

47

Page 48: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

-- Y2: Canal de luminância do próximo pixel. -- Cb: Canal de crominancia compartilhado entre os pixeis. -- Cr: Canal de crominancia compartilhado entre os pixeis. -- syncFF: Início do bloco de sincronismo. -- sync001 e sync002: blocos de sincronismo. -- syncXY: bloco de sincronismo contendo informações sobre os fields. type stateMachine is (blank, Y1, Y2, Cb, Cr, syncFF, sync001, sync002, syncXY); signal state : stateMachine := blank;

-- Sinais de controle: -- Marca o começo(1)/fim(0) de linha: signal sav : std_logic;

signal firstPixel : std_logic; -- Indica se é o primeiro pixel de uma linha. signal vBlank : std_logic; -- Indica se está em vBlank. signal blankField : std_logic; -- Indica o "field" em que está ocorrendo o blank. signal vBlankLast : std_logic;

signal internalField : std_logic; -- Indica o "field" atual.

--Contadores internos de linha/coluna: signal internalRow : std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); signal internalCol : std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );

begin process(clock, enable, reset) variable vBlankBorder : std_logic := '0'; begin if(enable = '1') then if(reset = '1') then state <= blank; elsif(rising_edge(clock)) then case state is when blank => if(dataIn = SYNC_START) then state <= syncFF; else state <= blank; end if; when Y1 => state <= Cr; outCr <= dataIn; internalCol <= std_logic_vector(unsigned(internalCol) + 1); when Y2 => if(dataIn = SYNC_START) then state <= syncFF; else state <= Cb; outCb <= dataIn; end if; when Cb => state <= Y1; outY <= dataIn; when Cr => state <= Y2; outY <= dataIn; internalCol <= std_logic_vector(unsigned(internalCol) + 1); when syncFF => state <= sync001;

48

Page 49: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

when sync001 => state <= sync002; when sync002 => state <= syncXY; sav <= not dataIn(EAV_SAV_BIT); internalCol <= (others => '0');

if(dataIn(FIELD_BIT) /= internalField) then clockField <= '1'; -- Sobe clock na mudança de field. internalRow <= (others => '0'); else clockField <= '0'; internalRow <= std_logic_vector(unsigned(internalRow) + 1); end if;

internalField <= dataIn(FIELD_BIT); vBlank <= dataIn(BLANK_BIT);

vBlankBorder := (not vBlank) and dataIn(BLANK_BIT);

if(vBlankBorder = '1') then blankField <= not dataIn(FIELD_BIT); end if;

when syncXY => if(sav = '1') then state <= Cb; outCb <= dataIn; else state <= blank; end if; end case; end if; end if; end process;

col <= internalCol; row <= internalRow;

field <= internalField;

clockPixel <= not clock when (state = Y2 or state = Cr) else '0' when (state = Y1 or state = Cb) else '1';

clockLine <= not sav; -- Sobe no final da linha.

activeVideo <= '1' when ( vBlank = '0' or internalField /= blankField ) else '0';

end behaviour;

49

Page 50: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Diagrama RTL do circuito de entrada de vídeo

50

Page 51: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo B: Circuito controlador de memória RAM.

Descrição em VHDL do circuito controlador de memória RAM.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all;

use work.bits.all;use work.memory.all;

entity memorySSRam is port ( clock : in std_logic; -- Sinal de relógio de 200 MHz. enable : in std_logic; -- Habilita o circuito para realizar uma operação. op : in std_logic; -- Operação: '1' leitura, '0' escrita.

address : in std_logic_vector( 18 downTo 0 ); -- Endereço.

dataIn : in std_logic_vector( 31 downTo 0 ); -- Entrada de dados (escrita). dataOut : out std_logic_vector( 31 downTo 0 ); -- Saídas de dados (leitura).

nextOp : out std_logic; -- Em '1' indica a disponibilidade de realizar uma operação.

dataValid : out std_logic; -- Indica que o dado na saída de dados é válido.

-- Comunicação com a memória (ativos em '0'): memoryCE : out std_logic; -- Chip Enable. memoryCE2 : out std_logic; -- Chip Enable 2 (ativo em '1'). memoryCE2n : out std_logic; -- /Chip Enable 2.

memoryADV : out std_logic; -- Burst address advance. memoryADSP : out std_logic; -- Address status processor. memoryADSC : out std_logic; -- Address status cache controller.

memoryGW : out std_logic; -- Global write. memoryOE : out std_logic; -- Output enable.

memoryBWE : out std_logic; -- Byte write enable. memoryBWa : out std_logic; -- Byte write A. memoryBWb : out std_logic; -- Byte write B. memoryBWc : out std_logic; -- Byte write C. memoryBWd : out std_logic; -- Byte write D.

-- Endereço (enviado para a memória). memoryAddress : out std_logic_vector( 18 downTo 0 );

-- Bits de paridade. memoryDataParity : inout std_logic_vector( 3 downTo 0 );

--Barramento de dados. memoryData : inout std_logic_vector( 31 downTo 0 ) );end memorySSRam;

architecture behaviour of memorySSRam is --Máquina de estados: --waiting: Esperando uma operação. --readStart: Início da operação de leitura.

51

Page 52: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

--readMid: Ciclo intermediário da operação de leitura. --readEnd: Fim da operação de leitura. --writeStart: Início da operação de escrita. --writeEnd: Fim da operação de escrita. type stateMachine is (waiting, readStart, readMid, readEnd, writeStart, writeEnd); signal state : stateMachine := waiting;

signal addressBuffer : std_logic_vector( 18 downTo 0 ); signal dataBuffer : std_logic_vector( 31 downTo 0 );

signal opBuffer : std_logic; signal enableBuffer : std_logic;

begin

--Sinais de valores padrão. memoryCE <= '0'; memoryCE2 <= '1'; memoryCE2n <= '0'; memoryADV <= '1'; memoryADSP <= '1'; memoryBWE <= '1'; memoryBWa <= '1'; memoryBWb <= '1'; memoryBWc <= '1'; memoryBWd <= '1';

memoryAddress <= addressBuffer;

process(clock) begin --Ajusta os sinais para a próxima subida de clock. if(falling_edge(clock)) then case state is when waiting => if(enableBuffer = '1') then if(opBuffer = '1') then state <= readStart;

dataValid <= '0';

memoryOE <= '1'; memoryADSC <= '0'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); else state <= writeStart;

memoryOE <= '1'; memoryADSC <= '0'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); end if; else state <= waiting;

52

Page 53: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

memoryOE <= '1'; memoryADSC <= '1'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); end if; when readStart => state <= readMid;

memoryOE <= '1'; memoryADSC <= '1'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z');

when readMid => state <= readEnd;

memoryOE <= '0'; memoryADSC <= '1'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); when readEnd => state <= waiting;

dataValid <= '1';

memoryOE <= '1'; memoryADSC <= '1'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); when writeStart => state <= writeEnd;

memoryOE <= '1'; memoryADSC <= '1'; memoryGW <= '0';

memoryData <= dataBuffer; memoryDataParity <= (others => '1'); -- Não é utilizado os bits de paridade.

when writeEnd => state <= waiting;

memoryOE <= '1'; memoryADSC <= '1'; memoryGW <= '1';

memoryData <= (others => 'Z'); memoryDataParity <= (others => 'Z'); end case;

53

Page 54: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

end if; if(rising_edge(clock)) then case state is when waiting => if(enable = '1') then nextOp <= '0'; else nextOp <= '1'; end if; addressBuffer <= address; dataBuffer <= dataIn; opBuffer <= op; enableBuffer <= enable; when readEnd => dataOut <= memoryData; nextOp <= '1'; when writeEnd => nextOp <= '1'; when others => nextOp <= '0'; end case; end if; end process;

end behaviour;

54

Page 55: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Diagrama RTL do circuito controlador de memória RAM.

55

Page 56: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

56

Page 57: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo C: Circuito ordenador de operações de memória.

Descrição em VHDL do circuito ordenador de operações na memória.

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;

use work.bits.all;use work.memory.all;

entity memoryDualPort is generic ( addressBusSize : natural := 19; -- Tamanho do barramento de endereço. dataBusSize : natural := 32 -- Tamanho do barramento de dados. ); port ( clock : in std_logic; -- Sinal de relógio da memória (~200MHz). clockRead : in std_logic; -- Sinal de relógio da leitura. clockWrite : in std_logic; -- Sinal de relógio da escrita.

opEnable : in std_logic; -- Habilita a realização de operações. readEnable : in std_logic; -- Habilita a operação de leitura. writeEnableA : in std_logic; -- Habilita a operação de escrita A. writeEnableB : in std_logic; -- Habilita a operação de escrita B.

addressRead : in std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereçode leitura. addressWriteA : in std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereçode escrita A. addressWriteB : in std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereçode escrita B.

dataInA : in std_logic_vector( dataBusSize - 1 downTo 0 ); -- Dados escritos pela operação A. dataInB : in std_logic_vector( dataBusSize - 1 downTo 0 ); -- Dados escritos pela operação B.

-- Interface com o controlador de memória. memoryEnable : out std_logic; -- Habilita o controlador. memoryOp : out std_logic; -- Operação: '1' leitura, '0' escrita. memoryAddress : out std_logic_vector( addressBusSize - 1 downTo 0 ); -- Endereço da operação. memoryDataWrite : out std_logic_vector( dataBusSize - 1 downTo 0 ) -- Dados a serem escritos. );end memoryDualPort;

architecture behaviour of MemoryDualPort is --Máquina de estados: --noop: sem operação, estado de espera. --writeA: Estado de primeira escrita. --writeB: Estado de segunda escrita. --read: Estado leitura. type stateMachine is (noop, writeA, writeB, read); signal state : stateMachine := noop;

signal nextOp : std_logic; signal address : std_logic_vector( addressBusSize - 1 downTo 0 );

57

Page 58: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

signal enable : std_logic; signal op : std_logic;

signal readRequest : std_logic; signal writeRequestA : std_logic; signal writeRequestB : std_logic;

signal readReset : std_logic; signal writeResetA : std_logic; signal writeResetB : std_logic;

signal addressBufferB : std_logic_vector( addressBusSize - 1 downTo 0 ); signal addressBufferA : std_logic_vector( addressBusSize - 1 downTo 0 ); signal dataInBufferA : std_logic_vector( dataBusSize - 1 downTo 0 ); signal dataInBufferB : std_logic_vector( dataBusSize - 1 downTo 0 );

signal addressBufferR : std_logic_vector( addressBusSize - 1 downTo 0 ); signal clockReadLast : std_logic; signal clockWriteLast : std_logic;

begin process(clock) variable readClockBorder : std_logic := '0'; variable writeClockBorder : std_logic := '0'; begin if(falling_edge(clock)) then --Identificador de borda: clockReadLast <= clockRead; clockWriteLast <= clockWrite; readClockBorder := ((not clockReadLast) and clockRead); writeClockBorder := ((not clockWriteLast) and clockWrite); --Requisição de leitura: if(readClockBorder = '1') then readRequest <= readEnable; addressBufferR <= addressRead; elsif(readReset = '1') then readRequest <= '0'; end if; --Requisição de escrita: if(writeClockBorder = '1') then writeRequestA <= writeEnableA; addressBufferA <= addressWriteA; dataInBufferA <= dataInA; writeRequestB <= writeEnableB; addressBufferB <= addressWriteB; dataInBufferB <= dataInB; elsif(writeResetA = '1' or writeResetB = '1') then if(writeResetA = '1') then writeRequestA <= '0'; end if; if(writeResetB = '1') then writeRequestB <= '0'; end if; end if; -- Ordenador de operações: case state is when noop => writeResetA <= '0';

58

Page 59: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

writeResetB <= '0'; readReset <= '0'; if(opEnable = '1') then if(writeRequestA = '1') then state <= writeA; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferA; memoryDataWrite <= dataInBufferA; elsif(writeRequestB = '1') then state <= writeB; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferB; memoryDataWrite <= dataInBufferB; elsif(readRequest = '1') then state <= read; memoryEnable <= '1'; memoryOp <= '1'; memoryAddress <= addressBufferR; memoryDataWrite <= (others => '0'); else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; when writeA => writeResetA <= '1'; writeResetB <= '0'; readReset <= '0'; if(opEnable = '1') then if(writeRequestB = '1') then state <= writeB; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferB; memoryDataWrite <= dataInBufferB; elsif(readRequest = '1') then state <= read; memoryEnable <= '1'; memoryOp <= '1'; memoryAddress <= addressBufferR; memoryDataWrite <= (others => '0'); else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if;

59

Page 60: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; when writeB => writeResetA <= '0'; writeResetB <= '1'; readReset <= '0'; if(opEnable = '1') then if(writeRequestA = '1') then state <= writeA; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferA; memoryDataWrite <= dataInBufferA; elsif(readRequest = '1') then state <= read; memoryEnable <= '1'; memoryOp <= '1'; memoryAddress <= addressBufferR; memoryDataWrite <= (others => '0'); else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; else state <= noop; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; when read => writeResetA <= '0'; writeResetB <= '0'; readReset <= '1'; if(opEnable = '1') then if(writeRequestA = '1') then state <= writeA; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferA; memoryDataWrite <= dataInBufferA; elsif(writeRequestB = '1') then state <= writeB; memoryEnable <= '1'; memoryOp <= '0'; memoryAddress <= addressBufferB; memoryDataWrite <= dataInBufferB; else state <= noop; memoryEnable <= '0'; memoryOp <= '0';

60

Page 61: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; else state <= read; memoryEnable <= '0'; memoryOp <= '0'; memoryAddress <= (others => '0'); memoryDataWrite <= (others => '0'); end if; end case; end if; end process;end behaviour;

61

Page 62: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Diagrama RTL do circuito ordenador de operações de memória.

62

Page 63: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo D: Circuito controlador de VGA.

Descrição em VHDL do circuito controlador de VGA.

library ieee;use ieee.math_real.all;use ieee.numeric_std.all;use ieee.std_logic_1164.all;

library util;use util.bits.all;use util.counter.all;

entity VGAController is generic( --Valores padrão para 640x480 60Hz hRes : natural := 640; -- Resolução horizontal do vídeo. vRes : natural := 480; -- Resolução vertical do vídeo.

hFrontPorch : natural := 16; -- 'Pixeis' do 'FrontPorch' horizontal. hSyncPulse : natural := 96; -- 'Pixeis' do 'SyncPulse' horizontal. hBackPorch : natural := 48; -- 'Pixeis' do 'FrontPorch' horizontal.

vFrontPorch : natural := 10; -- 'Linhas' do 'FrontPorch' vertical. vSyncPulse : natural := 2; -- 'Linhas' do 'SyncPulse' vertical. vBackPorch : natural := 33; -- 'Linhas' do 'FrontPorch' vertical.

clockBorder : border := rising; -- Borda do clock: 'rising' (subida, padrão) ou 'falling' (descida). clockFrameBorder : border := rising -- Borda do clock do quadro: 'rising' (subida, padrão) ou 'falling' (descida). );

port ( clock : in std_logic; -- Sinal de relógio do pixel. enable : in std_logic; -- Habilita o circuito. reset : in std_logic; -- Reinicia o circuito.

row : out std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); -- Linha do pixel col : out std_logic_vector( nBits(hRes - 1) - 1 downTo 0 ); -- Coluna do pixel

hBlank : out std_logic; -- '1' se em sincronismo horizontal. vBlank : out std_logic; -- '1' se em sincronismo de quadro.

hSync : out std_logic; -- Pulso hsync vSync : out std_logic; -- Pulso vsync

clockFrame : out std_logic -- Gera uma subida quando um quadro acabar. );

end VGAController;

architecture behaviour of VGAController is constant colMax : natural := hRes + hFrontPorch + hSyncPulse + hBackPorch - 1; constant rowMax : natural := vRes + vFrontPorch + vSyncPulse + vBackPorch - 1;

signal clkLine : std_logic := '0';

63

Page 64: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

signal colCount : std_logic_vector( nBits(colMax) - 1 downTo 0 ) := (others => '0'); signal rowCount : std_logic_vector( nBits(rowMax) - 1 downTo 0 ) := (others => '0');

begin -- Contador das colunas colCounter : counterSync generic map (finish => colMax, borderIn => clockBorder, borderOut => clockBorder) port map (reset => reset, clock => clock, enable => enable, clockOut => clkLine, count => colCount);

-- Contador das linhas rowCounter : counterSync generic map (finish => rowMax, borderIn => clockBorder, borderOut => clockFrameBorder) port map (reset => reset, clock => clkLine, enable => enable, clockOut => clockFrame, count => rowCount);

hSync <= '1' when (unsigned(colCount) > hRes + hFrontPorch - 1 and unsigned(colCount) < hRes + hFrontPorch + hSyncPulse ) else '0';

vSync <= '1' when (unsigned(rowCount) > vRes + vFrontPorch - 1 and unsigned(rowCount) < vRes + vFrontPorch + vSyncPulse ) else '0';

hBlank <= '1' when ( unsigned(colCount) > hRes - 1 ) else '0';

vBlank <= '1' when ( unsigned(rowCount) > vRes - 1 ) else '0';

col <= colCount( col'length - 1 downTo 0 ) when ( unsigned(colCount) < hRes ) else (others => '0');

row <= rowCount( row'length - 1 downTo 0 ) when ( unsigned(rowCount) < vRes ) else (others => '0');

end behaviour;

-------------------------------------------------------------Contador-----------------------------------------------------------

library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;

use work.bits.all;

entity counterSync is generic( -- Último valor válido do contador. Intervalo da contágem: [0, finish]. finish : natural; -- Borda do clock de entrada: 'rising' (subida, padrão) ou 'falling' (descida). borderIn : border := rising; -- Borda do clock de saída: 'rising' (subida, padrão) ou 'falling' (descida). borderOut : border := rising;

64

Page 65: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

-- Modo de operação do reset: synchronous (síncrono, padrão) ou asynchronous (assíncrono). resetMode : synchronism := synchronous );

port ( reset : in std_logic; -- Reset clock : in std_logic; -- Clock enable : in std_logic; -- Habilitador

clockOut : out std_logic; -- Gera um clock com o último bit da contagem count : out std_logic_vector( nBits(finish) - 1 downTo 0 ) -- Valor do contador );end counterSync;

architecture behaviour of counterSync is constant numBits : natural := nBits(finish); signal aux : std_logic_vector( numBits - 1 downTo 0 );begin process(clock) variable counter : natural range 0 to 2**numBits - 1 := 0; begin if(resetMode = asynchronous and enable = '1' and reset = '1') then counter := 0; elsif(edge(clock, borderIn)) then if(enable = '1') then if(resetMode = synchronous and reset = '1') then counter := 0; else if(counter = finish) then counter := 0; else counter := counter + 1; end if; end if; end if; end if; aux <= std_logic_vector(to_unsigned(counter,count'length)); end process;

clockOut <= condInverter(aux(numBits - 1), isRising(borderOut)); count <= aux;

end behaviour;

65

Page 66: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Diagrama RTL do circuito controlador de VGA.

66

Page 67: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo E: Circuito de teste do controlador de VGA.

library ieee;use ieee.math_real.all;use ieee.numeric_std.all;use ieee.std_logic_1164.all;

library util;use util.bits.all;use util.counter.all;use util.memory.all;

library video;use video.vga.all;

entity VGAOutput is port( CLOCK_28 : in std_logic;

VGA_CLK : out std_logic;

VGA_HS : out std_logic; VGA_VS : out std_logic;

VGA_BLANK : out std_logic; VGA_SYNC : out std_logic;

VGA_R : out std_logic_vector(9 downTo 0); VGA_G : out std_logic_vector(9 downTo 0); VGA_B : out std_logic_vector(9 downTo 0) ); end VGAOutput;

architecture Test of VGAOutput is --Circuito de PLL gerado pelo quartus: component clockVga is port( inclk0 : in std_logic := '0'; c0 : out std_logic ); end component clockVga;

constant dataBusSize : natural := 8; constant rows : natural := 480; constant cols : natural := 640; constant addressBusSize : natural := nBits(cols*rows - 1); --Entradas:---------------------------- signal clock : std_logic := '0'; signal reset : std_logic := '0'; signal enable : std_logic := '1'; --------------------------------------- signal addr : std_logic_vector(addressBusSize-1 downTo 0); signal data : std_logic_vector(dataBusSize-1 downTo 0); --Saídas:------------------------------ signal row : std_logic_vector( nBits(480 - 1) - 1 downTo 0 ); signal col : std_logic_vector( nBits(640 - 1) - 1 downTo 0 );

signal hPorch : std_logic;

67

Page 68: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

signal vPorch : std_logic;

signal hSync : std_logic; signal vSync : std_logic;

signal clockFrame : std_logic;

signal Y : std_logic_vector( 9 downTo 0 ); --------------------------------------begin clockGen : clockVga port map (inclk0 => CLOCK_28, c0 => clock);

VGA_CLK <= clock; VGA_HS <= not hSync; VGA_VS <= not vSync;

VGA_BLANK <= '1'; VGA_SYNC <= '1';

VGA_R <= Y when (vPorch or hPorch) = '0' else (others => '0'); VGA_G <= Y when (vPorch or hPorch) = '0' else (others => '0'); VGA_B <= Y when (vPorch or hPorch) = '0' else (others => '0');

-- Geração do padrão da imagem de saída: Y <= (others => '1') when (unsigned(col) < 320 and unsigned(row) < 240) or (unsigned(col) > 319 and unsigned(row) > 239) else (others => '0');

controler : VGAController port map ( clock => clock, reset => reset, enable => enable, row => row, col => col, hBlank => hPorch, vBlank => vPorch, hSync => hSync, vSync => vSync, clockFrame => clockFrame);

end Test;

68

Page 69: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo F: Circuito de teste do controlador e ordenador de memória.

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;

library util;use util.bits.all;use util.memory.all;

library video;use video.vga.all;

entity MemTestVGA2 is generic( channelSize : natural := 8; hres : natural := 640; -- Resolução horizontal do vídeo. vres : natural := 480 -- Resolução vertical do vídeo. ); port( CLOCK_28 : in std_logic; CLOCK_50 : in std_logic;

VGA_CLK : out std_logic;

VGA_HS : out std_logic; VGA_VS : out std_logic;

VGA_BLANK : out std_logic; VGA_SYNC : out std_logic;

VGA_R : out std_logic_vector(9 downTo 0); VGA_G : out std_logic_vector(9 downTo 0); VGA_B : out std_logic_vector(9 downTo 0);

SRAM_CLK : out std_logic;

SRAM_ADDR : out std_logic_vector( 18 downTo 0 );

SRAM_ADSC_N : out std_logic; SRAM_ADSP_N : out std_logic; SRAM_ADV_N : out std_logic;

SRAM_BE_N : out std_logic_vector(3 downTo 0);

SRAM_CE1_N : out std_logic; SRAM_CE2 : out std_logic; SRAM_CE3_N : out std_logic;

SRAM_GW_N : out std_logic; SRAM_OE_N : out std_logic; SRAM_WE_N : out std_logic;

SRAM_DQ : inout std_logic_vector( 31 downTo 0 ) );end MemTestVGA2;

architecture behaviour of MemTestVGA2 is

69

Page 70: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

component clockVga is port( inclk0 : in std_logic := '0'; c0 : out std_logic ); end component clockVga;

component clock200 is port( inclk0 : in std_logic := '0'; c0 : out std_logic ); end component clock200;

signal d0 : std_logic_vector(channelSize - 1 downTo 0); signal d1 : std_logic_vector(channelSize - 1 downTo 0); signal clockPixelVga : std_logic;

signal addressRead : std_logic_vector(nBits(hRes*vres - 1) - 1 downTo 0) := (others => '0'); signal addressWriteA : std_logic_vector(nBits(hRes*vres - 1) - 1 downTo 0) := (others => '0'); signal addressWriteB : std_logic_vector(nBits(hRes*vres - 1) - 1 downTo 0) := (others => '0'); signal address : std_logic_vector(nBits(hRes*vres - 1) - 1 downTo 0) := (others => '0'); signal dIn : std_logic_vector(31 downTo 0); signal dOut : std_logic_vector(31 downTo 0); signal enable : std_logic; signal op : std_logic;

signal enableRead : std_logic;

signal clockMemory : std_logic; signal nextOp : std_logic := '1';

signal hPorch : std_logic; signal vPorch : std_logic; signal hSync : std_logic; signal vSync : std_logic;

signal rowVga : std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); signal colVga : std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );

signal clockFrame : std_logic; signal dataValid : std_logic;

signal dataWrite : std_logic_vector(31 downTo 0); signal writeEnableA : std_logic; signal writeEnableB : std_logic; signal clockWrite : std_logic;begin

clockGenVga : clockVga port map (inclk0 => CLOCK_28, c0 => clockPixelVga); clockGenMem : clock200 port map (inclk0 => CLOCK_50, c0 => clockMemory);

70

Page 71: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

-- Clock de escrita: process(CLOCK_28) begin if(rising_edge(CLOCK_28)) then clockWrite <= not clockWrite; end if; end process;

process(clockWrite) variable col : natural := 0; variable row : natural := 0; variable count : natural := 0; begin if(falling_edge(clockWrite)) then --Escrita do padrão na memória: if(count < 600) then writeEnableA <= '1'; writeEnableB <= '1'; addressWriteA <= std_logic_vector(to_unsigned((row*hres) + col, addressWriteA'length)); addressWriteB <= std_logic_vector(to_unsigned(((row+1)*hres) + col, addressWriteB'length)); -- Geração do padrão: if( col < 320 and row < 240 ) or ( col > 319 and row > 239 ) then dIn <= ( others => '1' ); else dIn <= ( others => '0' ); end if; if(col < hRes)then col := col + 1; else col := 0; if(row < vres) then row := row + 1; else row := 0; count := count + 1; end if; end if; else --Para a escrita depois de um período. writeEnableA <= '0'; writeEnableB <= '0'; end if; end if; end process;

acessMemory : memoryDualPort generic map ( addressBusSize => 19, dataBusSize => 32 ) port map ( clock => clockMemory, clockRead => clockPixelVga, clockWrite => clockWrite, opEnable => nextOp,

71

Page 72: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

readEnable => '1', writeEnableA => writeEnableA, writeEnableB => writeEnableB, addressRead => addressRead, addressWriteA => addressWriteA, addressWriteB => addressWriteB,

dataInA => dIn, dataInB => dIn, memoryEnable => enable, memoryOp => op, memoryAddress => address, memoryDataWrite => dataWrite );

frameBuffer : memorySSRam port map ( clock => clockMemory, enable => enable, op => op, nextOp => nextOp, address => address, dataIn => dataWrite, dataOut => dOut, dataValid => dataValid, memoryAddress => SRAM_ADDR, memoryData => SRAM_DQ, memoryCE => SRAM_CE1_N, memoryCE2 => SRAM_CE2, memoryCE2n => SRAM_CE3_N, memoryADV => SRAM_ADV_N, memoryADSP => SRAM_ADSP_N, memoryADSC => SRAM_ADSC_N, memoryGW => SRAM_GW_N, memoryOE => SRAM_OE_N, memoryBWE => SRAM_WE_N, memoryBWa => SRAM_BE_N(0), memoryBWb => SRAM_BE_N(1), memoryBWc => SRAM_BE_N(2), memoryBWd => SRAM_BE_N(3) );

SRAM_CLK <= clockMemory;

process(clockPixelVga) begin if(falling_edge(clockPixelVga)) then if((vPorch or hPorch) = '0') then addressRead <= std_logic_vector(unsigned(addressRead) + 1); elsif(vPorch = '1') then addressRead <= (others => '0'); end if; end if; end process; controler : VGAController port map ( clock => clockPixelVga, reset => '0', enable => '1', row => rowVga, col => colVga, hBlank => hPorch, vBlank => vPorch, hSync => hSync, vSync => vSync, clockFrame => clockFrame );

-- Ajustando os valores lidos da memória para a saída: process(dataValid) begin if(rising_edge(dataValid)) then case addressRead(1 downTo 0) is when "00" => d0 <= dOut(7 downTo 0); when "01" =>

72

Page 73: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

d0 <= dOut(15 downTo 8); when "10" => d0 <= dOut(23 downTo 16); when "11" => d0 <= dOut(31 downTo 24); end case; end if; end process;

process(clockPixelVga) begin if(rising_edge(clockPixelVga)) then d1 <= d0; end if; end process;

VGA_CLK <= clockPixelVga; VGA_HS <= not hSync; VGA_VS <= not vSync; VGA_BLANK <= '1'; VGA_SYNC <= '1';

VGA_R(VGA_R'length - 1 downTo channelSize) <= (others => '0'); VGA_G(VGA_G'length - 1 downTo channelSize) <= (others => '0'); VGA_B(VGA_B'length - 1 downTo channelSize) <= (others => '0');

VGA_R(channelSize - 1 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0'); VGA_G(channelSize - 1 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0'); VGA_B(channelSize - 1 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0');

end behaviour;

73

Page 74: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

74

Page 75: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

Anexo G: Circuito de teste de repetição da entrada na saída.

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;

library util;use util.bits.all;use util.memory.all;

library video;use video.vga.all;

entity VinVout is generic( hres : natural := 640; -- Resolução horizontal do vídeo. vres : natural := 480 -- Resolução vertical do vídeo. ); port( CLOCK_28 : in std_logic; CLOCK_50 : in std_logic; TD1_DATA : in std_logic_vector(7 downTo 0); TD1_CLK27 : in std_logic; TD1_RST_N : out std_logic; VGA_CLK : out std_logic;

VGA_HS : out std_logic; VGA_VS : out std_logic;

VGA_BLANK : out std_logic; VGA_SYNC : out std_logic;

VGA_R : out std_logic_vector(9 downTo 0); VGA_G : out std_logic_vector(9 downTo 0); VGA_B : out std_logic_vector(9 downTo 0);

SW : in std_logic_vector(17 downTo 0);

SRAM_CLK : out std_logic;

SRAM_ADDR : out std_logic_vector( 18 downTo 0 );

SRAM_ADSC_N : out std_logic; SRAM_ADSP_N : out std_logic; SRAM_ADV_N : out std_logic;

SRAM_BE_N : out std_logic_vector( 3 downTo 0 );

SRAM_CE1_N : out std_logic; SRAM_CE2 : out std_logic; SRAM_CE3_N : out std_logic;

SRAM_GW_N : out std_logic; SRAM_OE_N : out std_logic; SRAM_WE_N : out std_logic;

75

Page 76: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

SRAM_DQ : inout std_logic_vector( 31 downTo 0 ) );end VinVout;

architecture behaviour of VinVout is

component VideoInputController is generic ( busSize : natural := 8 ); port ( clock : in std_logic; enable : in std_logic; reset : in std_logic;

dataIn : in std_logic_vector(busSize - 1 downTo 0);

outY : out std_logic_vector(busSize - 1 downTo 0); outCb : out std_logic_vector(busSize - 1 downTo 0); outCr : out std_logic_vector(busSize - 1 downTo 0); field : out std_logic; activeVideo : out std_logic; row : out std_logic_vector( nBits(vres - 1) - 1 downTo 0 ); col : out std_logic_vector( nBits(hres - 1) - 1 downTo 0 );

clockPixel : out std_logic; clockLine : out std_logic; clockField : out std_logic ); end component VideoInputController; component clockVga is port( inclk0 : in std_logic := '0'; c0 : out std_logic ); end component clockVga;

component clock200 is port( inclk0 : in std_logic := '0'; c0 : out std_logic ); end component clock200;

signal reset : std_logic; signal enable : std_logic; signal data : std_logic_vector(7 downTo 0);

signal Y : std_logic_vector(7 downTo 0); signal Cb : std_logic_vector(7 downTo 0); signal Cr : std_logic_vector(7 downTo 0);

signal dOut : std_logic_vector(31 downTo 0); signal dataWrite : std_logic_vector(31 downTo 0);

signal dIn : std_logic_vector(31 downTo 0); signal d0 : std_logic_vector(7 downTo 0);

76

Page 77: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

signal d1 : std_logic_vector(7 downTo 0);

signal active : std_logic;

signal clockPixel : std_logic; signal clockLine : std_logic; signal clockField : std_logic; signal clockPixelVga : std_logic;

signal addressWriteA : std_logic_vector( nBits(vRes*hRes - 1) - 1 downTo 0 ); signal addressWriteB : std_logic_vector( nBits(vRes*hRes - 1) - 1 downTo 0 ); signal addressRead : std_logic_vector( nBits(vRes*hRes - 1) - 1 downTo 0 ); signal address : std_logic_vector( nBits(vRes*hRes - 1) - 1 downTo 0 );

signal hPorch : std_logic; signal vPorch : std_logic; signal hSync : std_logic; signal vSync : std_logic;

signal clockFrame : std_logic; signal clockMemory : std_logic;

signal writeEnableA : std_logic; signal writeEnableB : std_logic;

signal memoryEnable : std_logic;

signal nextOp : std_logic; signal op : std_logic; signal dataValid : std_logic;

signal rowVga : std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); signal colVga : std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );

signal rowVin : std_logic_vector( nBits(vRes - 1) - 1 downTo 0 ); signal colVin : std_logic_vector( nBits(hRes - 1) - 1 downTo 0 );begin

clockGenVga : clockVga port map (inclk0 => CLOCK_28, c0 => clockPixelVga); clockGenMem : clock200 port map (inclk0 => CLOCK_50, c0 => clockMemory); enable <= '1'; reset <= '0';

TD1_RST_N <= '1';

videoIn : VideoInputController port map ( clock => TD1_CLK27, enable => enable, reset => reset, dataIn => TD1_DATA, outY => Y, outCb => Cb, outCr => Cr, field => open, activeVideo => active, clockPixel => clockPixel, clockLine => clockLine, clockField => clockField, row => rowVin, col => colVin ); process(clockPixel) begin

77

Page 78: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

if(rising_edge(clockPixel)) then if(enable = '1') then if(active = '1') then writeEnableA <= not SW(0); writeEnableB <= '0'; else writeEnableA <= '0'; writeEnableB <= '0'; end if; addressWriteA <= std_logic_vector(unsigned(rowVin)*hRes + unsigned(colVin)); addressWriteB <= std_logic_vector((unsigned(rowVin)+1)*hRes + unsigned(colVin)); dIn(7 downTo 0) <= Y; dIn(15 downTo 8) <= Y; dIn(23 downTo 16) <= Y; dIn(31 downTo 24) <= Y; end if; end if; end process; acessMemory : memoryDualPort generic map ( addressBusSize => 19, dataBusSize => 32 ) port map ( clock => clockMemory, clockRead => clockPixelVga, clockWrite => clockPixel, opEnable => nextOp, readEnable => '1', writeEnableA => writeEnableA, writeEnableB => writeEnableB, addressRead => addressRead, addressWriteA => addressWriteA, addressWriteB => addressWriteB,

dataInA => dIn, dataInB => dIn, memoryEnable => memoryEnable, memoryOp => op, memoryAddress => address, memoryDataWrite => dataWrite ); frameBuffer : memorySSRam port map ( clock => clockMemory, enable => memoryEnable, op => op, nextOp => nextOp, address => address, dataIn => dataWrite, dataOut => dOut, dataValid => dataValid, memoryAddress => SRAM_ADDR, memoryData => SRAM_DQ, memoryCE => SRAM_CE1_N, memoryCE2 => SRAM_CE2, memoryCE2n => SRAM_CE3_N, memoryADV => SRAM_ADV_N, memoryADSP => SRAM_ADSP_N, memoryADSC => SRAM_ADSC_N, memoryGW => SRAM_GW_N, memoryOE => SRAM_OE_N,

78

Page 79: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

memoryBWE => SRAM_WE_N, memoryBWa => SRAM_BE_N(0), memoryBWb => SRAM_BE_N(1), memoryBWc => SRAM_BE_N(2), memoryBWd => SRAM_BE_N(3) ); controler : VGAController port map ( clock => clockPixelVga, reset => '0', enable => enable, row => rowVga, col => colVga, hBlank => hPorch, vBlank => vPorch, hSync => hSync, vSync => vSync, clockFrame => clockFrame );

SRAM_CLK <= clockMemory; process(clockPixelVga) begin if(falling_edge(clockPixelVga)) then if((vPorch or hPorch) = '0') then addressRead <= std_logic_vector(unsigned(addressRead) + 1); elsif(vPorch = '1') then addressRead <= (others => '0'); end if; end if; end process; process(dataValid) begin if(rising_edge(dataValid)) then case addressRead(1 downTo 0) is when "00" => d0 <= dOut(7 downTo 0); when "01" => d0 <= dOut(15 downTo 8); when "10" => d0 <= dOut(23 downTo 16); when "11" => d0 <= dOut(31 downTo 24); end case; end if; end process; process(clockPixelVga) begin if(rising_edge(clockPixelVga)) then d1 <= d0; end if; end process;

VGA_CLK <= clockPixelVga; VGA_HS <= not hSync; VGA_VS <= not vSync; VGA_BLANK <= '1'; VGA_SYNC <= '1';

VGA_R(VGA_R'length - 1 downTo 8) <= (others => '0'); VGA_G(VGA_G'length - 1 downTo 8) <= (others => '0'); VGA_B(VGA_B'length - 1 downTo 8) <= (others => '0');

VGA_R(7 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0');

79

Page 80: Interface para processamento de imagens implementada em FPGA · desejou resolver e com baixa capacidade de correção caso um erro no projeto tenha sido detectado após a fabricação

VGA_G(7 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0'); VGA_B(7 downTo 0) <= d1 when (vPorch or hPorch) = '0' else (others => '0');

end behaviour;

80