Pós-Graduação em Ciência da Computação "SynMaker : Uma Ferramenta de Síntese de Alto Nível para Processamento Digital de Imagem" Por Luis Carlos da Silva Júnior Dissertação de Mestrado Universidade Federal de Pernambuco [email protected] www.cin.ufpe.br/~posgraduacao RECIFE, SETEMBRO/2013 UNIVERSIDADE FEDERAL DE PERNAMBUCO CENTRO DE INFORMÁTICA PÓS-GRADUAÇÃO EM CIÊNCIA DA COMPUTAÇÃO LUIS CARLOS DA SILVA JÚNIOR "SynMaker: Uma Ferramenta de Síntese de Alto Nível Para Processamento Digital de Imagem" ESTE TRABALHO FOI APRESENTADO À PÓS-GRADUAÇÃO EM CIÊNCIA DA COMPUTAÇÃO DO CENTRO DE INFORMÁTICA DA UNIVERSIDADE FEDERAL DE PERNAMBUCO COMO REQUISITO PARCIAL PARA OBTENÇÃO DO GRAU DE MESTRE EM CIÊNCIA DA COMPUTAÇÃO. ORIENTADOR: Prof. Dr. Cristiano Coêlho de Araújo RECIFE, SETEMBRO/2013 Catalogação na fonte Bibliotecária Jane Souto Maior, CRB4-571 Silva Júnior, Luis Carlos da SynMaker: uma ferramenta de síntese de alto nível para processamento digital de imagem / Luis Carlos da Silva Júnior. - Recife: O Autor, 2013. xi, 94 f., il., fig., tab. Orientador: Cristiano Coêlho de Araújo. Dissertação (mestrado) - Universidade Federal de Pernambuco. CIn, Ciência da Computação, 2013. Inclui referências e anexo. 1. Engenharia da computação. 2. Síntese de alto nível. 3. Processamento de imagem. 4. FPGA. I. Araújo, Cristiano Coêlho de (orientador). II. Título. 621.39 CDD (23. ed.) MEI2014 – 010 Dissertação de Mestrado apresentada por Luis Carlos da Silva Júnior à PósGraduação em Ciênciada Computação do Centro de Informática da Universidade Federal de Pernambuco, sob o título “SynMaker: Uma Ferramenta de Síntese de Alto Nível para Aplicações de Processamento Digital de Imagem em FPGA” orientada pelo Prof. Cristiano Coêlho de Araújo e aprovada pela Banca Examinadora formada pelos professores: ______________________________________________ Prof. Abel Guilhermino da Silva Filho Centro de Informática / UFPE ______________________________________________ Prof. João Marcelo Natario Teixeira Departamento de Estatística e Informática / UFRPE _______________________________________________ Prof. Cristiano Coêlho de Araújo Centro de Informática / UFPE Visto e permitida a impressão. Recife, 13 de setembro de 2013 ___________________________________________________ Profa. Edna Natividade da Silva Barros Coordenadora da Pós-Graduação em Ciência da Computação do Centro de Informática da Universidade Federal de Pernambuco. Dedico este trabalho, especialmente ao meu pai,a minha mãe, a toda minha família e aos meus amigos por todo carinho, compreensão, incentivo. AGRADECIMENTOS Gostaria de registrar meus sinceros agradecimentos às pessoas que contribuíram direta ou indiretamente, para realização desse trabalho. Ao meu Orientador Professor Cristiano Coêlho Araújo por toda paciência, disponibilidade, dedicação ao desenvolvimento da pesquisa e comentários coerentes. Aos professores Tsang Ing Ren, Edna Barros, Ricardo Massa, Paulo Maciel e pelos conhecimentos repassados, especial a Abel Guilhermino e João Marcelo Natario que apesar de tudo, concordaram em participar da Banca Examinadora e tiveram muita paciência, atenção e compreenção , meus sinceros muito obrigado. Aos meus Pais (Luis Carlos da Silva e Maria Cristina Ferreira) e Familiares pelo apoio em toda minha trajetória. A todos meus amigos e amigas que me apoiaram nos momentos mais difíceis. Aos meus amigos do grupo de estudo Paulo Guedes, Zílcio Sales, Marília Lima e Wilson Gondim que me ajudaram na pesquisa e desenvolvimento deste trabalho. Ao CIn e seus funcionários por me proporcionarem um ambiente agradável para que eu pudesse desenvolver este trabalho, em especial a Maria Lilia que desempenhou um papel primordial para que eu pudesse apresentar essa dissertação. A Deus por todos os dias da minha vida, pela saúde, paz, amor, família e tudo mais que Ele me proporcionou. “Ninguém abre um livro sem que se aprenda alguma coisa” (Anônimo) RESUMO Nesta dissertação de mestrado é introduzida uma nova ferramenta de síntese de alto nível chamada SynMaker que recebe como entrada um código de alto nível Orientado a Objetos escrito em Java ou SystemVerilog e gera código RTL que pode ser sintetizado para uma placa de prototipação alvo. A geração de código RTL leva em conta características do código orientado a objetos tais como classes, abstração, encapsulamento e algumas restrições relativas a polimorfismo, herança, utilização de construtores dentre outras especificadas neste trabalho e, por fim, integra o resultado com uma plataforma FPGA que inclui uma câmera e um display para exibir os resultados. O fluxo de projeto implementado no SynMaker foi especialmente concebido para aplicações de processamento de imagem e vídeo. Uma vantagem desta abordagem é que ela abstrai completamente o fluxo da ferramenta Quartus II, o designer descreve a aplicação de processamento de imagem em uma linguagem de alto nível de orientação a objeto, utilizando uma biblioteca de componentes da plataforma e gera código para a Plataforma de Desenvolvimento Terasic DE2-70. Esta plataforma de desenvolvimento inclui uma câmera digital e display, sendo uma plataforma ideal para a prototipagem de aplicações de filtros de processamento de imagem e vídeo. Em seu estado atual o SynMaker pode executar uma síntese de alto nível de uma forma simplificada, realizando um mapeamento direto de uma AST (Abstract Syntax Tree) para código RTL. Os resultados experimentais para a síntese de filtros de processamento de imagem são apresentados e demonstram a eficácia do funcionamento da ferramenta de síntese proposta. Palavras-chave: Síntese de alto nível - Field Programmable Gate Array (FPGA) processamento digital de imagem. ABSTRACT This dissertation introduces a new tool for high level synthesis called SynMaker that receives as input a high level code written in Object Oriented Java or SystemVerilog and generates RTL code that can be synthesized for a target board prototyping. The RTL code generation takes into account the characteristics of object-oriented code such as classes, abstraction, encapsulation and some restrictions concerning polymorphism, inheritance, use of constructors among others specified in this work and, finally, integrates the result with a platform FPGA that includes a camera and a display for displaying the results. The design flow implemented in SynMaker is specially designed for applications in image processing and video. One advantage of this approach is that it completely abstracts the flow of the Quartus II tool, the designer describes the application of image processing in a high-level language for object orientation, using a library of platform components and generates code for the Platform development Terasic DE2-70. This development platform includes a digital camera and display, is an ideal platform for prototyping applications of image processing filters and video. In its current state the SynMaker can perform a high-level synthesis in a simplified form, performing a direct mapping of an AST (Abstract Syntax Tree) to RTL code. The experimental results for the synthesis of the image processing filters are shown, and demonstrate the effectiveness of operation of the proposed synthesis tool. Keywords: High-level synthesis (HLS) - Field Programmable Gate Array (FPGA) digital image process. LISTA DE FIGURAS Figura 1. Convenção dos eixos para representação de imagens digitais [24]. ............... 15 Figura 2. Passos fundamentais em processamento de imagens digitais [24]. ................ 17 Figura 3. O Universo dos ASICs. ................................................................................... 19 Figura 4. Seqüência de projeto ASICs. .......................................................................... 19 Figura 5. Representação dos elementos básicos de um FPGA. ...................................... 22 Figura 6. Arquitetura interna de circuitos programáveis FPGA. .................................... 22 Figura 7. Processo de projeto de circuitos. ..................................................................... 25 Figura 8. Diagrama-Y segundo GAJSKI [22]. ............................................................... 26 Figura 9. Processo de síntese no diagrama-Y. ................................................................ 28 Figura 10. Metodologia manual de design de sistema.................................................... 29 Figura 11. Fluxo de projeto RTL. ................................................................................... 31 Figura 12. Desafios do projeto para 65nm e abaixo. ...................................................... 32 Figura 13. Fluxo de síntese de alto nível. ....................................................................... 33 Figura 14. Curva de aprendizagem. ................................................................................ 34 Figura 15. Um benefício da automação: exploração. ..................................................... 34 Figura 16. Entrada e saída do JavaCC. ........................................................................... 36 Figura 17. Compilando o parser gerado pelo JavaCC e usando-o para obter a AST. .... 36 Figura 18. Metodologia de projeto de hardware SystemC. ............................................ 42 Figura 19. Fluxo básico do Impulse C. ........................................................................... 45 Figura 20. Visão global do funcionamento .................................................................... 48 Figura 21. Visão RTL de parte do projeto base utilizado pelo SynMaker. (a) Projeto base padrão. (b) Projeto Base alterado pelo SynMaker após a síntese. .......................... 49 Figura 22. Fluxograma de síntese do SynMaker. ........................................................... 51 Figura 23. Fluxo de pré-compilação do SynMaker ........................................................ 53 Figura 24. Tela de Simulação. (a) Vídeo de entrada. (b) Vídeo de saída. ...................... 54 Figura 25. Fluxo de otimização. ..................................................................................... 55 Figura 26. Exemplo de código SystemVerilog gerado pela síntese. .............................. 56 Figura 27. Metodologia de síntese do SynMaker para classe, função e sua respectiva interface RTL.................................................................................................................. 57 Figura 28. Visão geral da metodologia de síntese de alto nível do SynMaker. ............. 58 Figura 29. Seqüência de comandos executados pelo Quartus. ....................................... 59 Figura 30. Arquitetura SynMaker................................................................................... 61 Figura 31. Placa de desenvolvimento Altera D2-70. ...................................................... 64 Figura 32. Estrutura de componentes e comunicação da placa D2-70. .......................... 64 Figura 33. Placa TRDB-D5M......................................................................................... 65 Figura 34. Placa TRDB-LTH. ........................................................................................ 65 Figura 35. Dispositivo FPGA EP2C70F896C6. ............................................................. 66 Figura 36. Estrutura interna do FPGA EP2C70F896C6................................................. 67 Figura 37. Altera DE2-70 Digital Camera Development Platform. (a) Projeto Base. (b) Projeto base alterado pelo SynMaker com o filtro de sobel. .......................................... 69 LISTA DE TABELAS Tabela 1. Lista de fabricantes e seus blocos lógicos. ........................................................ 21 Tabela 2. Fabricantes e ferramentas CAE. ........................................................................ 24 Tabela 3. Domínios de descrição x níveis de abstração e seus componentes. .................. 27 Tabela 4. Comparação entre ferramentas de síntese.......................................................... 46 Tabela 5. Testes de validação realizados ........................................................................... 68 Tabela 6. Resultado da síntese do SynMaker para filtros de processamento de imagem . 69 SUMÁRIO 1 INTRODUÇÃO .................................................................................................... 13 2 DISCUSSÃO TEÓRICA...................................................................................... 15 2.1 PROCESSAMENTO DIGITAL DE IMAGEM ................................................. 15 2.1.1. Imagem digital ............................................................................................ 15 2.1.2. Passos fundamentais utilizados no processamento de imagens ................. 16 2.2 SISTEMAS DIGITAIS ....................................................................................... 17 2.2.1. Circuitos lógicos programáveis em campo ................................................ 20 2.3 FPGA .................................................................................................................. 21 2.3.1. Elementos básicos de um FPGA................................................................. 21 2.3.2. Estrutura interna ........................................................................................ 22 2.3.3. Aplicações com FPGA ................................................................................ 23 2.3.4. Ferramentas CAE de síntese ...................................................................... 24 2.4 SÍNTESE NO CONTEXTO DE PROJETO DE CIRCUITOS ........................... 25 2.4.1. Fluxo de projeto de circuitos digitais ......................................................... 25 2.4.2. Domínios de representação ........................................................................ 26 2.4.3. Níveis de abstração .................................................................................... 27 2.5 METODOLOGIA MANUAL DE PROJETO DE CIRCUITO .......................... 28 2.6 SÍNTESE DE ALTO NÍVEL .............................................................................. 30 2.7 JAVA PARSER .................................................................................................. 35 2.7.1. JAVACC ...................................................................................................... 35 2.8 REPRESENTAÇÃO INTERMEDIÁRIA E EXTRAÇÃO DE INFORMAÇÃO (DIAGRAMA) ........................................................................................................... 36 2.8.1. Árvore sintática abstrata (AST).................................................................. 37 2.8.2. Análise léxica e sintática ............................................................................ 37 2.8.3. Análise de fluxo de controle ....................................................................... 38 2.8.1. Análise de fluxo de dados ........................................................................... 38 2.8.2. Grafo de fluxo de controle e dados ............................................................ 39 3 REVISÃO DA LITERATURA ........................................................................... 40 3.1 TRABALHOS RELACIONADOS .................................................................... 40 3.2 FERRAMENTAS DE SÍNTESE DE ALTO NÍVEL.......................................... 40 3.2.1. Systemc ....................................................................................................... 41 3.2.2. Catapult C .................................................................................................. 43 3.2.3. Impulse C .................................................................................................... 44 3.2.4. Análise comparativa ................................................................................... 45 4 FERRAMENTA DE SÍNTESE: SYNMAKER ................................................. 47 4.1 ARQUITETURA ALVO DO SYNMAKER ...................................................... 48 4.2 FLUXO E MODELAGEM DO SISTEMA ........................................................ 49 4.2.1. Descrição comportamental ........................................................................ 51 4.2.2. Processador de comandos de síntese ......................................................... 52 4.2.1. Pré-compilador HLS .................................................................................. 53 4.2.2. Simulação ................................................................................................... 53 4.2.3. Compilador HLS ......................................................................................... 54 4.2.4. Síntese de alto nível .................................................................................... 55 4.2.5. Gerador RTL .............................................................................................. 58 4.2.6. Plataforma FPGA ....................................................................................... 59 4.3 ARQUITETURA DO SYNMAKER .................................................................. 60 5 EXPERIMENTOS E TESTES DE VALIDAÇÃO ............................................ 62 5.1 AMBIENTE ....................................................................................................... 62 5.1.1. Requisitos e instalação ............................................................................... 62 5.1.2. Terasic DE2-70 .......................................................................................... 63 5.1.3. O FPGA EP2C70: Circuito lógico reconfigurável .................................... 66 5.2 EXECUÇÃO ...................................................................................................... 67 5.3 ANÁLISE E INTERPRETAÇÃO ...................................................................... 69 6 CONSIDERAÇÕES FINAIS ............................................................................... 71 6.1 CONTRIBUIÇÕES ............................................................................................ 71 6.2 TRABALHOS FUTUROS ................................................................................. 71 REFERÊNCIAS ........................................................................................................... 72 7 ANEXO .................................................................................................................. 76 1 INTRODUÇÃO A necessidade de projetar cada vez mais rapidamente circuitos digitais fez a Síntese de Alto Nível ou High Level Synthesis (HLS) parecer ser uma alternativa interessante, quando comparado ao design RTL. O uso de HLS permite a síntese de algoritmos para arquiteturas e apesar de tais ferramentas serem desenvolvidas visando tecnologias ASIC, HLS atualmente atrai um grande interesse para os projetistas de FPGA. Em trabalhos como [13] e [16] experimentos mostram que a solução HLS pode conseguir uma boa redução no uso de recursos de FPGAs com uma produtividade de design melhorada em relação ao projeto RTL codificado manualmente. Historicamente, aplicações que foram implementadas em código RTL escrito à mão para um FPGA normalmente fornecem uma boa qualidade nos resultados (em termos de desempenho e eficiência), mas baixa produtividade. Desta forma, ferramentas de síntese de alto nível com alvos em FPGAs buscam oferecer o melhor de dois mundos: a boa qualidade dos resultados com elevados níveis de produtividade. Para algumas aplicações, especialmente aquelas que necessitam de execução em tempo real, a velocidade é um requisito fundamental. Conforme [31], essas aplicações possuem requisitos específicos, tais como processamento de grande volume de dados e curtos intervalos de tempo para processar. Um exemplo deste tipo de aplicação é o processamento digital de imagem e vídeo. Além disso, o uso de processamento de imagem possui grande aplicação em estudos de robótica, automóvel, sistemas vídeomonitorados e técnicas OCR (Optical Character Recognition) para reconhecimento de caracteres da imagem, em dispositivos como scanners. Esse tipo de implementação em plataformas reconfiguráveis baseadas em dispositivos FPGA tem uma participação cada vez maior nas pesquisas acadêmicas em relação a outras tecnologias já consagradas, tais como a computação paralela, DSP (Digital Signal Processor) ou ASIC (Application Specific Integrated Circuit). A justificativa do uso de FPGAs deve-se a flexibilidade de adaptação e configuração, juntamente com o alto desempenho e seu baixo custo de aquisição. Durante o estudo para este trabalho de mestrado foi identificado que existe uma demanda de aplicações de processamento de imagem e vídeo em tempo real. Outro aspecto importante que foi levantado em consideração, é que existe um espaço importante para a implementação destas aplicações utilizando-se a tecnologia de FPGA. Porém o esforço de projeto para a implementação em FPGA ainda é um obstáculo para a sua adoção. Desta forma, existe uma motivação para se desenvolver uma ferramenta de síntese de alto nível para aplicações de processamento de imagem em arquitetura FPGA. A utilização de uma ferramenta como esta, visa reduzir o time-to-market de inserção do produto no mercado, facilidade e maior flexibilidade do designer no desenvolvimento de projetos desse tipo para FPGA, já que com a ferramenta o designer se aproveitará da facilidade de implementação dos algoritmos em uma linguagem de alto nível, tal como Java. O Java constitui umas das linguagens mais utilizadas no mercado, contendo uma grande quantidade de desenvolvedores e documentação de fácil acesso, além de ser uma linguagem de fácil aprendizagem, manuseio e que contém orientação a objetos bem estruturada, com todos os conceitos desse paradigma incorporados. A placa DE2-70 tem constantemente se mantida na frente das demais placas educacionais se diferenciando por sua abundância de interfaces para acomodar varias aplicações, especificamente para 13 aplicações de processamento digital de imagem esta placa FPGA faz parte da Altera Digital Camera Development Platform, que proporciona ao desenvolvedor acesso e fácil manipulação a dados e alta qualidade de imagens. Devido a isso o Java foi escolhido como a linguagem de entrada para ferramenta de síntese e a plataforma para exibição do resultado final. Existem muitas ferramentas HLS, mas nenhuma delas é capaz de fazer síntese de alto nível de um programa Java ou SystemVerilog com nicho em aplicação de processamento de imagem digital para trabalhar em uma placa Terasic DE2-70 com uma plataforma de Desenvolvimento de Câmera Digital. Como pode ser visto, por um lado, há uma falta de metodologia e ferramentas para programadores de software mais familiarizados com o Java para projetar para uma plataforma de hardware. Por outro lado, os designers de SystemVerilog são obrigados a trabalhar no nível RTL para a síntese, aumentando o seu esforço de projeto, tempo e erros. Sendo assim, neste trabalho é apresentada uma ferramenta que recebe como entrada um código de processamento de imagem orientado a objeto, e o mesmo é sintetizado até seu funcionamento na plataforma de vídeo e câmera da placa DE2-70 da Altera. Esta ferramenta, chamada SynMaker, é capaz de sintetizar algoritmos de processamento de imagem desenvolvidos em Java ou SystemVerilog, gerando uma descrição de hardware que pode ser automaticamente programada na plataforma de desenvolvimento de Câmera Digital da Altera. Como resultado, é aumentada a produtividade dos usuários de FPGA atuais, que desejam fazer aplicações específicas de processamento de imagens aplicadas em plataforma FPGA ou apenas gerar descrição RTL que pode ser utilizada em outro projeto que o designer desejar. A contribuição deste trabalho é uma nova ferramenta projetada para realizar a síntese de alto nível aplicada a algoritmos baseados em FPGA para processamento digital de imagens utilizando como entrada código Java ou SystemVerilog com algumas restrições sobre o uso da linguagem, como o uso de a polimorfismo, herança e utilização de construtores. Além disso, esta ferramenta contém um novo parser SystemVerilog e uma nova representação intermediária chamada Generic Abstract Sintax Tree ( GAST) para unificar diferentes árvores de sintaxe abstratas geradas por diferentes parsers. Esta dissertação descreve o projeto e desenvolvimento de uma ferramenta para realização de síntese de alto nível. Ao final do projeto, a ferramenta deverá ser capaz de receber uma descrição do comportamento do sistema em diferentes linguagens de descrição (Java e SystemVerilog), realizar algumas otimizações, gerar como saída um conjunto de arquivos e um projeto do sistema descrito em uma linguagem de descrição de hardware. Este conjunto de saída poderá então ser processado por uma ferramenta de prototipação rápida, para compilação e síntese em uma determinada plataforma-alvo. Em particular, no escopo desta dissertação deverá ser possível sintetizar, realizar síntese RTL de sistemas para a plataforma Terasic DE2-70 [38]. O resto da dissertação está organizado nos seguintes capítulos. O capítulo de discussão teórica envolve todo conhecimento necessário que o usuário precisa ter sobre o tema que consiste desde o básico sobre o FPGA até síntese de alto nível. O capítulo de revisão da literatura discute os trabalhos relacionados à síntese de alto nível em FPGA e algumas ferramentas que estão presentes em trabalhos acadêmicos ou no mercado. O capítulo SynMaker apresenta a ferramenta desenvolvida. O capítulo Experimentos apresenta como foram executados os experimentos e a análise dos resultados da síntese, e por fim, o capítulo de considerações finais demonstra uma conclusão de tudo que foi desenvolvido e aprendido com o trabalho e o que poderá ser feito no futuro. 14 2 DISCUSSÃO TEÓRICA Neste Capítulo serão abordados os conceitos de processamento digital de imagem, sistemas digitais, FPGA, além de uma descrição de sistema de síntese para circuitos, ferramentas CAE para síntese e uma introdução a síntese de alto nível. 2.1 PROCESSAMENTO DIGITAL DE IMAGEM O processamento de imagens digitais pode ser empregado em áreas como medicina, cinema, indústria, entre outras. O seu objetivo é a melhoria da informação visual para interpretação humana e o processamento de dados de cenas para percepção automática, ou seja, com auxílio de máquinas. 2.1.1. IMAGEM DIGITAL Uma imagem digital pode ser definida como uma função bidimensional, f(x, y), em que x e y são coordenadas espaciais, e a amplitude de f, em qualquer par de coordenadas (x, y) é chamada de intensidade também denominada de nível de cinza da imagem no determinado ponto. Quando x e y e os valores da amplitude de f são todos finitos, quantidades discretas, a imagem é chamada de imagem digital. A área de processamento digital de imagens refere-se ao processamento de imagens por meio de um computador digital. A imagem na Figura 1 pode ser representada por uma função bidimensional de f(x, y), onde x e y indicam as coordenadas espaciais e f(x, y) indica a intensidade do nível de cinza da imagem na dada coordenada (x, y). Figura 1. Convenção dos eixos para representação de imagens digitais [24]. 15 A imagem digital é uma imagem f(x, y) discretizada, tanto em coordenadas espaciais quanto em brilho, e pode ser representada computacionalmente como uma matriz MxN, onde o cruzamento de linha com coluna indica um ponto na imagem, e o valor contido naquele ponto indica a intensidade de brilho, ou seja, o nível de cinza contido naquele ponto. Os pontos em uma imagem são chamados de pixels (“Picture Elements”). A Matriz 1 abaixo representa um exemplo de um formato descritivo de uma imagem digital. ( , )= (0,0) (1,0) … ( − 1,0) (0,1) (1,1) … ( − 1,1) … … … … (0, (1, ( − 1) − 1) … − 1, − 1) Matriz 1. Formato descritivo de uma imagem digital. 2.1.2. PASSOS FUNDAMENTAIS UTILIZADOS NO PROCESSAMENTO DE IMAGENS Em [24], são apresentados importantes passos utilizados para a realização do processamento de imagens, essas etapas serão explicadas nesta seção. A Figura 2 mostra uma seqüência padrão para o reconhecimento de imagens, descritas a seguir: Domínio do problema: profunda análise do problema a ser tratado para se especificar o objetivo a ser alcançado. Aquisição de imagens: consiste em utilizar um equipamento para adquirir a imagem, como uma câmera de vídeo, uma câmera fotográfica digital, ou um digitalizador de imagens. Esse processo pode ser também chamado de digitalização, pois consiste na conversão de um sinal da forma analógica para a forma digital. Pré-processamento: refere-se ao processamento inicial da imagem para correção de distorções geométricas e remoção de ruídos, modificando a imagem para evidenciar características a serem utilizadas nas próximas etapas. Segmentação: consiste na etapa de processamento em que se analisa a imagem com relação à informação nela presente. A imagem é dividida em diferentes regiões que são, posteriormente, analisadas por algoritmos em busca de informações que a caracterizem. A segmentação consiste em extrair da imagem apenas as áreas que interessam para a resolução do problema. Base de conhecimento: representa o conhecimento adquirido pelo ser humano, o qual direciona o processamento da imagem para o melhor reconhecimento possível. 16 Representação e descrição: no processo de representação, as características principais devem ser enfatizadas e extraídas. O processo de descrição é também conhecido como seleção de características, onde são extraídas as características principais que resultam em informação quantitativa, capaz de separar classes de objetos importantes para o reconhecimento dos padrões. Reconhecimento e interpretação: consiste em atribuir rótulos aos objetos, classificando-os a partir das informações encontradas na imagem na etapa anterior. Esta etapa tenta aproximar o desempenho computacional ao do ser humano ao reconhecer padrões dentro de uma imagem. Figura 2. Passos fundamentais em processamento de imagens digitais [24]. Esta dissertação de mestrado trata de uma ferramenta de síntese de alto nível para algoritmos de processamento de imagem tendo como plataforma alvo uma placa que já possui recursos de aquisição de imagens. O SynMaker processa algoritmos que realizam as etapas de pré-processamento, segmentação, base do conhecimento e reconhecimento e interpretação. 2.2 SISTEMAS DIGITAIS Atualmente há um grande avanço na área da indústria eletrônica de Telecomunicações e Computação como: Sistemas de Comunicação sem Fio, GPSGlobal Positioning System, Sistemas de TVs a cabo, Microprocessadores e Memórias. Estes avanços foram possibilitados devido à capacidade tecnológica da microeletrônica que permitiu a integração de milhões de transistores em um único circuito integrado e de uma forma resumida temos as seguintes vantagens: Aumento da velocidade de operação do CI. Capacidade de realizar tarefas complexas. Maior confiabilidade. 17 Maior segurança de projeto. Redução de Custos. Menor tamanho físico. Para atender estas vantagens hoje temos diversas tecnologias comercialmente que são: Bipolares em Silício. Unipolares utilizando a tecnologia MOS em Silício. Semicondutores compostos tipo III-V como: (GAAS, LNP, etc.). Cada uma destas tecnologias apresenta vantagens e desvantagens em relação às outras em função da aplicação específica. Uma das tecnologias que tem se destacado muito no mercado e a tecnologia CMOS (Complementary Metal Oxide Semiconductor), estes transistores tem a vantagem de usar quase nenhuma energia quando não é preciso. Os Circuitos integrados ainda podem ser classificados de acordo com seu processo de fabricação: 1. Circuitos integrados monolíticos: Os elementos do circuito (diodos, transistores, resistências, condensadores, indutâncias, etc.) são criados essencialmente na massa e à superfície de um material semicondutor (por exemplo, silício impurificado (dopado), arsenieto de gálio, silício-germânio, fosfeto de índio), formando um todo indissociável. 2. Circuitos integrados híbridos: Reúnem de maneira praticamente indissociável, por interconexões ou cabos de ligação, sobre um mesmo substrato isolante (vidro, cerâmica, etc.) elementos passivos (resistências, condensadores, indutâncias, etc.) obtidos pela tecnologia dos circuitos de camada fina ou espessa e elementos ativos (diodos, transistores, circuitos integrados monolíticos, etc.), obtidos pela tecnologia dos semicondutores. Estes circuitos podem incluir também componentes discretos. 3. Circuitos integrados de múltiplos chips: Constituídos por dois ou mais circuitos integrados monolíticos interconectados, combinados de maneira praticamente indissociável, dispostos ou não sobre um ou mais substratos isolantes, mesmo com elementos de conexão, mas sem outros elementos de circuito ativos ou passivos. Esses circuitos integrados são produzidos de diversas maneiras, para suprir a necessidade do mercado foram desenvolvidas técnicas de projetos de circuitos integrados de aplicações especificas (ASICs) como: PLD´s (Dispositivos Lógicos Programáveis) - É um circuito monolítico com fusível, Anti-fusível, ou lógica baseada em célula de memória, que pode ser programado. FPGA (Field Programable Gate Array) - É um circuito composto de uma matriz de transistores MOS, sendo possível a programação do circuito através de softwares especializados como o MAXPLUS ou QUARTUS II da Altera. Gate Array - O circuito integrado monolítico composto de linhas e colunas detransistores. Standard Cell - É um circuito monolítico que é personalizado em todas as 18 camadas utilizando uma biblioteca que incorpora estruturas de circuitos précaracterizadas. Full Custom - É um circuito monolítico que pode ser projetado "manualmente", desde o início. Para entender melhor as vantagens e desvantagens dos ASICs convém estudar o diagrama da Figura 3, que mostra os tipos de ASICs em função: Figura 3. O Universo dos ASICs. Onde se pode concluir que o tipo de ASIC mais versátil e com maior capacidade de integração (Densidade) é o Full-Custom, mas também tem um elevado custo de desenvolvimento, demora muito tempo para chegar até o mercado e risco de não funcionar corretamente devido a sua complexidade (Imagine um processador com 9 milhões de transistores). Figura 4. Seqüência de projeto ASICs. 19 Para projetarem-se circuitos integrados deve-se primeiramente especificar o projeto a ser executado conforme mostra a Figura 4. Com base nas especificações do projeto devemos escolher qual tipo de ASICs atende melhor as especificações do projeto. E finalmente, a ferramenta de CAD apropriada. O FPGA foi escolhido para ser utilizado nessa dissertação por ser um intermediário entre custo de desenvolvimento e versatilidade. 2.2.1. CIRCUITOS LÓGICOS PROGRAMÁVEIS EM CAMPO Em 1961 surge o primeiro circuito integrado disponível comercialmente, com a junção de vários transistores em um só componente, colocando um circuito relativamente grande dentro de uma só pastilha de silício. Fatores como o mercado de eletro-eletrônicos em contínua expansão, consumidor mais exigente, empresas que buscam tecnologias capazes de aumentar a produção e a qualidade, diminuindo o tempo e custo final do produto, globalização e muitos outros, estão mudando o cenário dos ambientes de projetos de sistemas digitais e o perfil dos profissionais que trabalham nesta área. Originalmente existiam projetistas de hardware ou de software separadamente. Os modernos projetistas de sistemas computacionais dedicados devem possuir conhecimentos multidisciplinares, de arquitetura de computadores a desempenho de algoritmos de processamento digital de sinais. A computação reconfigurável introduziu novos paradigmas aos modelos computacionais atuais, tanto em nível de software quanto de hardware. Em muitos sistemas digitais como, ambientes de tempo real, os processadores de propósito geral não têm um desempenho satisfatório. Alguns recursos alternativos como processador digital de sinal (DSP) e processadores de aplicação específica melhoram o desempenho destes sistemas. Uma tecnologia relativamente nova é a implementação de circuitos de aplicações específicas em FPGAs (Field Programmable Gate Array). O rápido desenvolvimento da tecnologia ligada a dispositivos de lógica programável em nível de velocidade e capacidade permite aos projetistas implementar circuitos e arquiteturas cada vez mais complexas, sem a necessidade do uso de grandes recursos de fundição em silício. Sabendo que as maiorias desses circuitos são reprogramáveis, sua primeira aplicação seria em projetos de prototipagem, economizando consideravelmente tempo e custo, devido à agilidade e facilidade em todo o processo de desenvolvimento, simulação, teste, depuração e alteração do projeto. Dentre as vantagens da rápida realização de protótipos de sistemas computacionais, para aplicações dedicadas, usando tecnologia de circuitos programáveis, destacam-se: Maior velocidade de chegada do produto ao mercado consumidor, pela detecção antecipada de problemas quanto ao hardware do sistema. Maior confiabilidade do sistema, item chave para desenvolvimento de sistemas de tempo real ou biomédico. 20 Possibilidade de desenvolvimento conjunto de hardware e software, sem interdependências, de modo a aumentar a velocidade com que o produto final chega à linha de produção. 2.3 FPGA Os FPGAs estão se consolidando como um dos principais dispositivos configuráveis que permitem uma rápida prototipagem, reconfigurabilidade e baixo custo de desenvolvimento. Projetar circuitos e sistemas digitais usando-se dessa tecnologia é possível através de várias maneiras, sendo elas por programação com a linguagem VHDL, Verilog ou SystemVerilog. Os FPGAs são circuitos programáveis compostos por um conjunto de células lógicas ou blocos lógicos alocados em forma de uma matriz. Em algumas arquiteturas, os blocos lógicos possuem recursos seqüenciais tais como flip-flops e/ou registradores. Cada fabricante nomeia seu bloco lógico, podendo haver mais de um nome para um mesmo fabricante, como mostrado na Tabela 1. Fabricante Xilinx Actel Altera Nome do Bloco Lógico CLB (Configurable Logic Block) LM (Logic Modules) LE (Logic Element) para as séries 8000 e 10000. Macrocell para as séries 5000, 7000 e 9000. Tabela 1. Lista de fabricantes e seus blocos lógicos. Em geral, a funcionalidade destes blocos assim como seu roteamento é configurável via software. Os FPGAs, além de proporcionar um ambiente de trabalho simplificado e de baixo custo, possibilitam o projeto de um número virtualmente ilimitado de circuitos através da configuração do próprio dispositivo. 2.3.1. ELEMENTOS BÁSICOS DE UM FPGA A estrutura básica de um FPGA pode variar de fabricante para fabricante, de família para família ou até em uma mesma família pode existir variações, mas alguns elementos fundamentais são mantidos. Podem-se destacar três elementos fundamentais em um FPGA: CLB (Configurable Logic Block): bloco lógico configurável, unidade lógica de um FPGA. IOB (In/Out Block): bloco de entrada e saída, localizado na periferia dos FPGAs, são responsáveis pela interface com o ambiente. SB (Switch Box): caixa de conexão, responsável pela interconexão entre os CLBs, através dos canais de roteamento. Na Figura 5, tem-se a representação dos elementos básicos de um FPGA e sua disposição interna, destacando-se os CLBs, IOBs e SBs. 21 Figura 5. Representação dos elementos básicos de um FPGA. Nos últimos anos a quantidade de portas lógicas disponíveis num FPGA tem crescido num ritmo muitíssimo acelerado, possibilitando a implementação de arquiteturas cada vez mais complexas. Isto permite a implementação não apenas de protótipos, mas de produtos finais complexos baseados em FPGA’s. 2.3.2. ESTRUTURA INTERNA FPGAs são circuitos programáveis compostos de CLBs, switch boxes, IOBs e canais de roteamento, discutidos na subseção 2.3.1. A Figura 6 apresenta as quatro principais arquiteturas internas utilizadas em circuitos programáveis FPGA: matriz simétrica, sea-of-gates, row-based e PLD hierárquico. Figura 6. Arquitetura interna de circuitos programáveis FPGA. 22 A arquitetura sea-of-gates é um circuito composto por transistores ou blocos lógicos de baixa complexidade. A vantagem dessa arquitetura é a grande disponibilidade de portas lógicas por área. Porém, como não há uma área dedicada para o roteamento, é necessário que o mesmo seja feito sobre as células, muitas vezes inutilizando áreas disponíveis para implementação de uma determinada lógica. Nos circuitos de arquitetura row-base dos blocos lógicos estão dispostos horizontalmente. Existe uma área dedicada de roteamento localizada entre as linhas de blocos lógicos. As arquiteturas row-base de sea-of-gates originaram-se das metodologias de projeto de ASICs, standard-cells e gate-array. A arquitetura tipo PLD hierárquico é constituída por uma matriz de blocos lógicos, denominados logic arrays blocks, sendo interligados através do recurso de roteamento conhecido como matriz programável de interconexão (PIA). Esse tipo de dispositivo é dito hierárquico, porque os blocos lógicos podem ser agrupados entre si. A arquitetura tipo matriz simétrica é flexível no roteamento, pois possui canais verticais e horizontais. 2.3.3. APLICAÇÕES COM FPGA Tratando-se de FPGAs, um circuito flexível e poderoso, é difícil definir uma lista das áreas de aplicações, pois é uma tecnologia relativamente recente, onde a cada dia novas aplicações são implementadas. Porém, podem-se definir as áreas mais comuns de aplicações, citadas a seguir: Processamento de imagem e vídeo: sistemas de realidade aumentada e filtros de processamento de imagem. Consumo: Decodificador de áudio digital, arcade games, vídeo games e sistemas de karaokê. Transportes: Sistemas de estradas de ferro. Industrial: Equipamentos de teste e medidas, equipamentos médicos, controle remoto, robótica, emulador ASIC e sistemas de visão. Comunicação de Dados: Multiplexadores, roteadores, vídeo conferência, criptografia, modems, compressão de dados, LANs, HUBs, FDDI e Wireless LANs. Telecomunicação: Interfaces SONET, interfaces de fibras ópticas, ATM, interfaces ISDN, controlador de voice-mail, multiplexadores T1 e compressão de dados. Militar: Sistemas de computadores, comunicação e controle de fogo. Computadores: Interfaces de memória, controladores DMA, controladores de cache, coprocessadores SSP, multimídia e gráficos. Periféricos: Controladores de disco, controladores de vídeo, FAX, máquinas de caixa, modems, sistemas POS, cartões de aquisição de dados, terminais, impressoras, scanners e copiadoras. Uma área de aplicação que vem se destacando é a de sistemas de processamento de imagem e vídeo, onde se pode implementar em FPGA um sistema para processamento de imagem digitais com aplicações que vão de filtros de processamento de imagem até aplicações avançadas de visão computacional. 23 2.3.4. FERRAMENTAS CAE DE SÍNTESE As ferramentas Computer Aided Engineering (CAE) juntamente com as ferramentas de síntese evoluíram consideravelmente, possibilitando ao projetista desenvolver circuitos cada vez mais confiáveis e otimizados. Uma das funções da síntese é otimizar projetos desenvolvidos nas ferramentas CAE. Essa otimização pode ser controlada pelo projetista através de restrições impostas antes do processo de síntese. Essas restrições devem ser definidas cuidadosamente, pois poderão afetar o circuito final. Para reduzir a área do circuito e/ou aumentar a sua velocidade são exigidos dos projetistas conhecimentos específicos do projeto e técnicas de otimização. Algumas características das ferramentas CAE são: Especificação do comportamento do FPGA através de diagramas esquemáticos, linguagens de descrição de Hardware (HDL - Hardware Description Language) e/ou diagrama de fluxo (máquina de estados). Sintetização do circuito obedecendo às restrições impostas pelo projetista; não havendo restrições, a ferramenta de síntese busca a configuração padrão para a síntese do circuito. Verificação do funcionamento do circuito através de simulação funcional e temporal, já considerando os tempos de atraso gerados pela lógica resultante do processo de síntese. Capacidade de gerar relatórios estatísticos, com dados de comportamento e desempenho do circuito desenvolvido. Possibilidade de implementação do projeto em nível físico, fazendo com que o circuito programável assuma o comportamento descrito no projeto. A seguir exemplos de algumas ferramentas CAE para tecnologias baseadas em circuitos programáveis, FPGA: Fabricante Xilinx Altera Nome da Ferramenta CAE Xilinx Foundation Series Xilinx Foundation ISE MAX-PLUS MAX-PLUS II Quartus Quartus II Tabela 2. Fabricantes e ferramentas CAE. As ferramentas de síntese na maioria das vezes não são desenvolvidas pelos fabricantes de ferramentas CAE e sim por empresas especializadas nessa tecnologia específica, sendo atribuídas às ferramentas CAE posteriormente. Uma ferramenta CAE pode conter uma ou mais ferramentas de síntese. Dependendo do projeto, o desempenho de uma ferramenta de síntese pode ser melhor do que de outra, ficando com o projetista a responsabilidade de analisar e definir a melhor ferramenta para seu projeto. Daí, a importância de conhecer as vantagens e desvantagens de cada uma, para selecionar a ferramenta adequada. Para desenvolver o que foi proposto nessa dissertação foi utilizada a ferramenta CAE Quartus II, que realiza a etapa final de análise e síntese do código, depois que esse código foi sintetizado pela ferramenta proposta. 24 2.4 SÍNTESE NO CONTEXTO DE PROJETO DE CIRCUITOS A área de projeto de circuitos digitais tem sido o foco de uma grande quantidade de pesquisa, abordando vários aspectos de fluxo de projeto. Nesta seção serão apresentadas etapas do projeto de circuitos digitais, isto é, as etapas de modelagem, síntese e verificação, destacando importantes definições. 2.4.1. FLUXO DE PROJETO DE CIRCUITOS DIGITAIS O projeto de um circuito integrado é o processo de implementar uma funcionalidade desejada por meio do refinamento da especificação do sistema até chegar à sua implementação física. O processo de refinamento implica na elaboração de múltiplos modelos de sistema, que ao longo do processo vão dando ênfase gradual em diferentes aspectos do projeto, até que sua implementação seja finalmente realizada. Tais modelos conceituais podem ser concretizados em descrições ou representações por linguagens de descrição ou especificação, e de representações internas ou intermediárias. O conjunto de objetos que são usados para definir tais modelos está organizado em diferentes níveis de abstração e domínios de descrição. O projeto de sistemas é o processo de implementar uma funcionalidade desejada usando um conjunto de componentes físicos. Baseado nesse conceito, o processo de projetar o sistema deve começar com a especificação dessa funcionalidade com o suficiente nível de precisão que ofereça o detalhe requerido do sistema. A Figura 7 mostra uma típica estratégia de projeto top-down para circuitos. Figura 7. Processo de projeto de circuitos. 25 A saída consiste da implementação final, que resulta da integração heterogênea de arquiteturas realizada na etapa de síntese. Existem três etapas principais na estratégia de projeto: modelagem, síntese e validação [20]. Pela modelagem, a especificação inicial é transformada numa representação interna do projeto, a qual é manipulada seguidamente pelas tarefas de síntese e validação. Dentro do contexto do fluxo de projeto introduzido na Figura 7, os elementos abstratos da Representação Interna (RI) são misturados com a biblioteca da tecnologia, e com a tarefa de síntese produz uma implementação final do circuito digital, em forma de hardware/software [1], que satisfaz todos os requisitos. O processo moderno de síntese é realizado de maneira automática ou semiautomática, usando-se ferramentas de CAE, e está inserido, atualmente, na abordagem top-down. Visto que o processo de síntese tem como alicerce a RI usada, ele depende fortemente das características do modelo abstrato adotado. Pela validação, o projetista consegue garantir que a funcionalidade de sua implementação está correta. Tal garantia pode evitar o consumo de tempo na depuração em níveis inferiores de abstração e na interação para os altos níveis de abstração. A simulação é o método mais comum de teste da funcionalidade do sistema, ainda que a utilização de técnicas de verificação formal está crescendo em adoção [42]. 2.4.2. DOMÍNIOS DE REPRESENTAÇÃO O diagrama-Y, mostrado na Figura 8, é uma representação gráfica que é utilizada na representação de componentes e os domínios em que um projeto de circuito pode ser representado, segundo Gajski [22]. O diagrama possui três eixos, cada um representa um domínio de descrição que é dividido em múltiplos níveis de abstração. Figura 8. Diagrama-Y segundo GAJSKI [22]. 26 Existem três domínios de descrição: domínio comportamental, domínio estrutural e domínio físico. A descrição do projeto pode ser realizada em cada um desses domínios ou ter partes em diferentes domínios. No domínio comportamental o projeto é descrito pela funcionalidade desejada do sistema, definida como uma composição de entidades funcionais abstratas. Os objetos comportamentais são as peças de funcionalidade e são responsáveis por processar dados de entrada e produzir dados da saída. Em geral descrições comportamentais são usadas para modelar os dados e as dependências de controle entre eles, fazendo transformações funcionais. No domínio estrutural, a estrutura lógica é descrita freqüentemente como a interconexão estrutural de um conjunto de blocos abstratos. É o ponto intermediário entre os domínios comportamental e físico. Os objetos estruturais representam, por exemplo, modelos de componentes reais ou barramentos que estão processando dado o tempo todo. O domínio físico representa a implementação física do projeto, ou a realização dos componentes estruturais abstratos do domínio estrutural, incluindo também o posicionamento dos blocos abstratos no plano físico do sistema. Seguindo o que foi descrito acima, a ferramenta de síntese produzida neste trabalho é responsável por sintetizar um código que está inicialmente em um domínio comportamental para um domínio estrutural. 2.4.3. NÍVEIS DE ABSTRAÇÃO Analisando a Figura 8, percebe-se que os níveis de abstração recebem diferentes classificações dependendo dos tipos de objetos que os compõem. Estes estão divididos em: nível arquitetural ou de sistemas, nível algoritmico, nível de blocos funcionais ou RTL (Transferência de Registradores), nível lógico ou de portas lógicas, e nível de circuitos, onde no fluxo de projeto, os objetos dos níveis mais altos são transformados hierarquicamente por objetos dos níveis mais baixos [22]. A tabela 3 [4] apresenta uma visão mais detalhada dos níveis de abstração nos domínios de descrição. Nela são mostrados os objetos ou componentes de cada nível, de acordo com o domínio de descrição de projeto. Em relação às descrições feitas em cada nível de abstração é importante fazer as seguintes observações: Nível de Sistemas Nível Algorítmico Nível de Blocos Funcionais Nível Lógico Nível de Circuitos Domínio Comportamental Domínio Estrutural Domínio Físico Conjunto de especificações funcionais e de desempenho. Algoritmos. Manipulação de estruturas de dados. Operações de transferência de registradores. Seqüência entre estados. Equações booleanas. Equações diferenciais. CPUs, memórias, chaves, controladores, barramentos. Módulos de hardware. Estruturas de dados. Particionamento físico dos sistemas. ALUs, MUXs, Registradores. Floor plan Gates, flip-flops, latches. Transistores, capacitores, resistores. Estimativas de células. Estimativas de células, detalhes nas células. Clusters Tabela 3. Domínios de descrição x níveis de abstração e seus componentes. 27 No nível de sistemas, as descrições são de um sistema genérico onde os seus componentes de hardware e softwares podem estar ainda indefinidos, sendo que a implementação final pode resultar em componentes apenas de cada um dos tipos ou ambos. A partir do nível algorítmico até os níveis mais baixos da hierarquia as atividades de projeto tratam de descrições puramente de hardware. No diagrama-Y, cada ponto indica um modelo diferente de representação. De acordo com isso é possível dizer que um modelo é definido pelo grau de detalhamento da descrição do projeto no ponto considerado. O próprio projeto ou o fluxo de projeto também pode ser observado no diagrama-Y, como o processo de síntese exemplificado na Figura 9 [4]. Neste caso, no nível de sistemas, a síntese consiste no processo de derivar uma descrição estrutural do sistema - arquitetura do sistema – composta de componentes de hardware e software (processadores) a partir de uma descrição puramente comportamental do sistema, uma especificação do sistema que pode ser em uma linguagem natural, não sintetizável. Esse processo também é conhecido como síntese arquitetural ou co-projeto hardware-software, neste nível é onde esta inserida a proposta desse trabalho. Figura 9. Processo de síntese no diagrama-Y. 2.5 METODOLOGIA MANUAL DE PROJETO DE CIRCUITO A metodologia manual de projeto de um circuito começa com um engenheiro de sistema escrevendo um modelo de sistema em qualquer linguagem de alto nível. São verificados os conceitos e os algoritmos. Após os conceitos e algoritmos serem validados, as partes do modelo de alto nível são implementados em hardware, ou seja, convertidos manualmente para uma descrição VHDL ou Verilog para implementação em hardware. Isto é mostrado na Figura 10. Há certo número de problemas com esta abordagem. Dentre eles: Conversão manual de linguagem de alto nível para HDL implica em erros de tradução; 28 Com a metodologia manual, o designer cria o modelo em alto nível, verifica-se o modelo funciona como o esperado, e traduz o projeto manualmente em uma HDL. Este processo é muito tedioso e propenso a erros. Desconexão entre o Modelo de Sistema e descrição HDL; Após o modelo ser convertido em HDL, a descrição HDL se torna o foco do desenvolvimento. O modelo de alto nível torna-se rapidamente desatualizado a medida que as mudanças são feitas. Tipicamente mudanças são feitas apenas com a descrição HDL e não implementado no modelo de alto nível. Vários testes de sistema Os testes que são criados para validar a funcionalidade do modelo de alto nível normalmente não podem ser executados contra o modelo de HDL sem conversão. Não só o designer tem que converter o modelo de alto nível para HDL, mas o conjunto de teste tem de ser convertido para o ambiente HDL também. Para as partes do modelo original serem implementadas em software, o modelo muitas vezes deve ser reescrito com chamadas para um RTOS ( Real-time operating system). O modelo é o simulado e verificado com um RTOS emulador. Embora as partes do código original possam ser reutilizadas, a mudança na abstração do modelo original, para um modelo baseado em RTOS requer significativa recodificação e verificando as alterações manuais torna-se um problema significativo. Figura 10. Metodologia manual de design de sistema. 29 2.6 SÍNTESE DE ALTO NÍVEL A síntese é o termo usado para designar o processo de transformação de um sistema digital a partir de uma especificação comportamental em uma descrição a nível RTL comportamental ou estrutural que pode em seguida passar por ferramentas de síntese RTL. De um modo geral, a especificação inclui alguma forma de abstração, ou seja, algumas das decisões de design não claramente descritas. A implementação, por outro lado, deve descrever em detalhes o projeto completo em um determinado nível de abstração. Devido à complexidade dos sistemas digitais, especialmente aqueles implementados na tecnologia VLSI, o processo de síntese é geralmente dividido em várias etapas. Estes passos incluem síntese em nível de sistema, a síntese de alto nível, a síntese lógica e projeto físico. Síntese em nível de sistema atua de acordo com a formulação da arquitetura básica da implementação. Tal sistema pode ser implementado por um conjunto de processadores cooperantes, tais como ASIC, controladores dedicados, FPGAs e processadores DSP. A atribuição de um conjunto de processadores físicos e o mapeamento de processos, ou seja, funções a serem executadas na especificação comportamental para esses processadores é a decisão mais crítica de projeto a ser feita durante a etapa de síntese em nível de sistema. Uma característica importante do nível de sistema é que as técnicas de síntese e requisitos de projeto são aplicações altamente dependentes. Por exemplo, em nível de sistema, técnica de síntese utilizada na área de aplicação em sistemas de tempo real embutidos será muito diferente dos utilizados em sistemas de DSP. Síntese de alto nível, então, traduz a especificação comportamental de um processo para uma descrição estrutural que ainda é independente da tecnologia. Esta descrição estrutural geralmente está em nível RTL. Síntese em nível de sistema e síntese de alto nível forma o front-end de uma abordagem de síntese para o projeto do sistema digital. Síntese lógica e projeto físico são usados para mapear as estruturas implementadas a nível RTL em uma descrição de layout que é a implementação final. Síntese lógica e projeto físico formam o back-end da abordagem de síntese para o projeto de sistema digital. Uma razão importante para a separação do processo de síntese em front-end (sistema) e back-end de síntese pode ser atribuída à boa propriedade geral possuída pela síntese de front-end e da natureza de curta duração do processo para alvo semicondutores associado à síntese de back-end. Como a síntese front-end não está ligada a uma determinada tecnologia, ela pode ser utilizada em vários ambientes diferentes do projeto ou adotada rapidamente às novas tecnologias, conforme a necessidade. O back-end, no entanto tem um ciclo de vida muito curto, porque fica desatualizado com mudanças na tecnologia. Nos últimos anos, tem havido uma nítida tendência para automatizar o processo de síntese e há várias razões para isso: Menor ciclo de design. O uso da automação do processo de síntese reduz o tempo de projeto e oferece melhores chances de uma empresa para atingir a janela de mercado para aquele produto. Automação reduz também o custo dos produtos significativamente, uma vez que em muitos casos, o custo de criação do produto domina o custo de desenvolvimento. 30 A capacidade de explorar um espaço de projeto muito maior. Uma técnica de síntese eficiente pode produzir várias implementações a partir da mesma especificação em um curto período de tempo. Isso permite que o designer possa explorar diferentes trade-offs entre custo, desempenho, consumo de energia, testabilidade e etc. Suporte para verificação do projeto. Um pré-requisito para automatizar o processo de co-projeto de hardware / software, por exemplo, é iniciar o processo de síntese com uma especificação conjunta de ambos, hardware e software, este torna possível verificar completamente a consistência do projeto, consistindo em componentes de hardware e processos de software. Menos erros. A redução das atividades de concepção manuais significa que o número de erros humanos será diminuído, se os algoritmos de síntese podem ser validados. Pode-se ter mais confiança de que o projeto final será corretamente implementado seguindo a especificação dada. Aumento do acesso à tecnologia de circuitos integrados. Quanto mais alto o nível de abstração pode ser capturado e sintetizado automaticamente, mais fácil para as pessoas que não são especialistas em tecnologia CI’s para projetar chips. A complexidade dos circuitos digitais integrados tem sempre aumentado de uma tecnologia para outra. Os designers muitas vezes tiveram que se adaptar ao desafio de proporcionar soluções comercialmente aceitáveis, com um esforço razoável. Muitas evoluções (às vezes, revoluções) ocorreram no passado: back-end de automação ou lógica síntese foram parte daqueles, permitindo nova área de inovação. Graças ao crescente fator de integração oferecido por convergência de tecnologia, a complexidade na última SoC já atingiu dezenas de milhões de portas lógicas. Começando com 90 nm e abaixo disto, na Figura 11 mostra o fluxo para esse escopo [33]. Figura 11. Fluxo de projeto RTL. 31 A diferença entre a produtividade por designer e por ano e o aumento da complexidade do SoC, mesmo tendo em conta um número muito conservador de portas por melhoria de tecnologia, irá ocorrer uma explosão da mão de obra para SoCs para melhorias de nanotecnologia futuras como mostra a Figura 12. Figura 12. Desafios do projeto para 65nm e abaixo. Há uma grande necessidade de melhoria de produtividade em nível de design. Isto cria uma excelente oportunidade para novas técnicas de projeto a serem adotadas: designers enfrentam de frente este desafio, com uma fome de progredir e elevar o nível de abstração do modelo de referência em que eles confiam. Um novo passo é necessário para aumento da produtividade. Parte desta etapa pode ser oferecida por ESLD: Electronic System Level Design. Isso inclui HW / SW codesign e Síntese de Alto Nível ( High Level Synthesis, HLS). A implementação de HW / SW co-design ocorreu alguns anos atrás, graças à introdução de bibliotecas de descrição em alto nível de abstração como SystemC e codificação TLM [33]. A aplicação de HLS, porém, é nova e está apenas começando a ser implantada e aceita de forma comercial. A Figura 13 mostra a base da metodologia de concepção da STMicroelectronics baseada na utilização de descrições em código C. 32 Figura 13. Fluxo de síntese de alto nível. Nesta metodologia é utilizado como descrição de entrada do fluxo um modelo de referência bit-accurate descrito a nível funcional em C / C++ usando tipos de dados de SystemC ou tipo de dado equivalente. No caso ideal, esta descrição de nível C tem de ser extensivamente validada usando um testbench também nível C, em ambiente funcional, de modo a se tornar o modelo do fluxo de execução. Isto é facilitado pela velocidade de simulação deste modelo C, geralmente mais rápido do que outros tipos de descrição. Em seguida, tendo em conta as restrições de tecnologia, a ferramenta HLS produz uma representação RTL, compatível com fluxo RTL-GDS2. A verificação entre os modelos em C e RTL é feita utilizando-se ferramentas de verificação de equivalência seqüenciais, ou por extensas simulações. Iniciada em 2001, a pesquisa sobre os fluxos de novas ferramentas HLS permitiu que algumas implantações de dentro STMicroelectronics, a partir dev2004, com os primeiros simpatizantes. Vemos claramente em 2007 uma aceleração da demanda de designers. Os designers demonstram terem aumentado um fator de cinco vezes para dez vezes, em termos de produtividade pelo uso da metodologia de projeto em C, dependendo da forma como eles reutilizam no design de seus IPs, Figura 14. Mais promissor: Designers que mudaram para projeto em C normalmente não querem voltar ao nível RTL para criar seus IPs. Outro benefício desta automação de projeto de nível C, a reutilização de IP’s de processamento de sinal agora está se tornando realidade. A automação do fluxo permite se ter IPs em C, descritos a nível funcional, fácil de modificar e lidar com novas especificações e fácil de ressintetizar. Outro benefício: o tamanho da descrição do código escrito manualmente (C, em vez de RTL) é reduzido por um fator de aproximadamente 10 vezes. Isto reduz o tempo de modificação, assim como o número de erros funcionais manualmente introduzidos no silício final. 33 Figura 14. Curva de aprendizagem. Outro benefício das ferramentas de automação de HLS é a exploração de microarquitetura. Ou seja, o projetista pode gerar rapidamente várias micro-arquiteturas e selecionar aquela que mais se adéqua às especificações do projeto. A Figura 15 basicamente descreve uma mudança de paradigma: freqüência de clock pode ser parcialmente de correlata em restrições de throughput. Isto significa que, focando as restrições funcionais (throughput/latência), o designer pode explorar diversas soluções que satisfazem as especificações, usando várias freqüências de clock. Graças a possibilidade de produzir essas diferentes arquiteturas rapidamente pela ferramenta de HLS mudando a freqüência de clock, o projetista pode escolher o projeto de mais baixa velocidade que não terá a penalidade de área da solução de alta velocidade gerada. Figura 15. Um benefício da automação: exploração. A HLS está sendo implantada também para as necessidades de mais automação e mais otimização. Reordenação aritmética profunda é uma dessas necessidades, a corrente geração de ferramentas é efetivamente limitada em termos de reordenação aritmética. 34 A Capacidade das ferramentas de HLS é outro parâmetro a ser reforçado, mesmo que as ferramentas tenham progredido muito nos últimos anos. A bem conhecida Lei de Moore existe e ainda as ferramentas tem que seguir a capacidade de integração das indústrias de semicondutores. 2.7 JAVA PARSER Para os programadores, escrever um parser para a gramática sempre foi uma tarefa propensa a erros. Especialmente quando lidamos com uma gramática como Java que tem tantas aplicações. E também é uma tarefa demorada obter um parser para a gramática. Portanto, tem havido uma série de pesquisas sobre geração automática de um compilador de uma especificação formal de uma linguagem de programação. Nesta dissertação utilizamos destes conceitos para extrair informações valiosas a partir do código fonte dado como entrada. Por esse motivo, optou-se por usar um destas ferramentas de geração de parsers, presentes no estado da arte, em vez de escrever um parser próprio a partir do zero. Algumas dessas ferramentas para compilador bem conhecidas são: • Lex &Yacc: Lex constrói analisadores léxicos de expressões regulares. Yacc converte uma especificação de gramática em um compilador table-driven que pode produzir código quando ele tinha analisado com êxito produções da gramática. • Flex & Bison: Eles são projetos produzidos pela Free Software Foundation´s GNU, são versões melhoradas de Lex e Yacc para uso em plataformas que não executam um sistema operacional Unix ou derivados. • DFA & ANTLR (Componentes de PCCTS7): Eles oferecem as mesmas funções que Lex e Yacc. No entanto, as gramáticas ANTLR que aceita são LL(k) gramáticas, em oposição às gramáticas LALR utilizados por Yacc. Para essa dissertação foi utilizada a ferramenta Java Compiler Compiler (JavaCC) para esse propósito de gerar um parser tanto para Java quanto SystemVerilog. 2.7.1. JAVACC JavaCC (Java Compiler Compiler) é o gerador de parser mais popular para uso com aplicações construídas em Java [39]. É uma ferramenta que lê uma especificação de gramática e a converte para um programa Java que pode reconhecer uma descrição que corresponde à gramática de acordo com a especificação definida pelo criador da gramática. JavaCC foi lançado pela Sun com o nome JACK. A última versão foi lançada pela Metamata Inc. Web Gain1 foi a empresa zeladora dele por um tempo. Atualmente, JavaCC pode ser obtido a partir da Web a partir do site da Sun Micro system2. Além do próprio gerador de parser, JavaCC fornece outras capacidades normais relacionadas à 1 2 http://www.webgain.com http://javacc.dev.java.net/ 35 geração de parsers, tais como construção de árvore (via uma ferramenta chamada JJTree), as ações, depuração e etc. JavaCC não possui bibliotecas de tempo de execução (como arquivos JAR). Os únicos arquivos que são necessários para o parser são aqueles gerados pelo JavaCC. JavaCC é capaz de ler uma descrição de uma linguagem (a gramática) e gerar o código, escrito em Java, que irá ler e analisar essa linguagem. JavaCC é particularmente útil quando você tem que escrever código para lidar com uma linguagem de entrada que tem uma estrutura complexa. Neste caso, elaborar manualmente um módulo de entrada, sem a ajuda de um gerador de analisador pode ser uma tarefa difícil. O analisador léxico do parser JavaCC gerado tem um recurso para manter comentários quando eles são definidos como tokens especiais. Símbolos especiais são ignorados durante a análise, mas estes tokens estão disponíveis (ao contrário de itens ignorados, como espaços em branco) para o processamento pelas ferramentas. Na Figura 16, a entrada é composta de uma descrição da especificação da gramática da linguagem que é salva em um arquivo com extensão .jj. Uma vez processados se tem como saída os arquivos Java que tem o código do parser que pode processar a linguagem que está de acordo com a gramática no processo de especificação. Estes arquivos Java, quando são compilados, geram um compilador para a gramática que foi especificada. Figura 16. Entrada e saída do JavaCC. Uma vez que o código do parser é gerado, ele é compilado com o compilador Java (javac) para obter o parser. O código de resultado é usado para analisar a gramática desejada, veja a Figura 17. Figura 17. Compilando o parser gerado pelo JavaCC e usando-o para obter a AST. 2.8 REPRESENTAÇÃO INTERMEDIÁRIA E EXTRAÇÃO DE INFORMAÇÃO (DIAGRAMA) Nesta seção, apresentamos alguns modelos que usam técnicas para a extração de informações a partir do código fonte. Uma representação intermediária (RI) é uma estrutura de dados, geralmente construída a partir de uma descrição de um programa ou 36 sistema, dada na sua respectiva linguagem, que captura parcial ou completamente os detalhes da informação presente nessa descrição. Por exemplo, no contexto de síntese de alto nível (High Level Synthesis, HLS), existe o conceito de representação intermediária canônica [26] para a qual são mapeados os objetos e a semântica de um ou vários modelo abstratos, como, por exemplo, um CFG (Control Flow Graph), DFG (Data Flow Graph) ou um CDFG (Control Data Flow Graph). As RIs são criadas com o objetivo de manipular os dados do sistema, extraindoos e alterando-os ou, então realizando medições e estimativas. As RIs podem ser obtidas tanto por conversão, a partir das linguagens de especificação, ou como resultado de tarefas realizadas por ferramentas de auxílio de projeto (CAD). Como as RIs são construções utilizadas por outros programas, elas diferenciam-se das linguagens de especificação pela inexistência de um conjunto de elementos léxicos com regras sintáticas e semânticas. Uma RI permite uma exploração do espaço de soluções entre as possíveis implementações de um projeto; isto significa que ao escolher uma RI apropriada, pode-se facilitar o uso de diversas ferramentas para os processos subsequentes. O problema de extração de conhecimento do código do aplicativo foi investigado em diversas áreas de pesquisa, como a análise léxica e sintática, análise de fluxo de controle e dados, que serão detalhados nas próximas seções. Estas representações, ao exibirem explicitamente o paralelismo ao nível da operação, entre blocos básicos e entre ciclos considerando sempre a granulosidade da operação, permitem a exploração eficiente de implementações em hardware específico. 2.8.1. ÁRVORE SINTÁTICA ABSTRATA (AST) Uma AST captura a estrutura essencial da descrição de entrada do sistema digital numa forma de árvore, omitindo detalhes sintáticos desnecessários da linguagem de especificação. As ASTs omitem, por exemplo, a informação das marcas de pontuação da linguagem, tais como os ponto e vírgulas para terminar expressões ou declarações, ou vírgulas para separar argumentos de uma função. As ASTs são geralmente construídas seguindo um esquema bottom-up como a metodologia LALR usada pela ferramenta Bison, ou seguindo um esquema top-down como na metodologia LL(k) usado pela ferramenta ANTLR. Ao projetar os nós da árvore, uma escolha comum do projeto é determinar a granularidade de representação da AST. Isto é, se todas as construções da linguagem de especificação de entrada são representadas como um tipo diferente de nó na AST, ou se algumas construções da linguagem são representadas com um tipo comum de nó na AST e diferenciadas somente usando um valor numa certa variável. 2.8.2. ANÁLISE LÉXICA E SINTÁTICA Análise do código fonte requer a conversão para uma forma que pode ser facilmente processada por um programa. Uma árvore sintática abstrata (AST) é um tipo de representação de código-fonte que facilita o uso de árvores para a passagem algoritmos. Análise léxica e sintática de um código fonte, de acordo com a gramática livre de contexto da linguagem, gera uma AST. Gramáticas próprias são descritas numa 37 notação estilizada chamada Backus-Naur [16], em que as partes do programa são definidas por normas e, em termos dos seus constituintes. Uma AST é usada para mostrar como uma sentença em linguagem natural é dividida em seus componentes. O parser que é gerado pela ferramenta JavaCC produz AST a partir de um código fonte. Após a AST ser produzida, ela está pronta para ser analisada. 2.8.3. ANÁLISE DE FLUXO DE CONTROLE Depois de se obter a AST, esta é utilizada para a análise de fluxo de controle (Control Flow Analysis ou CFA) [19]. Existem dois tipos principais de CFA, análise inter-processual e Intra-processual. Análise inter-processual determina a relação entre chamadas de unidades do programa, enquanto a análise intra-processual determina a ordem em que os comandos são executados dentro dessas unidades de programa. Juntos, eles construem um gráfico de fluxo de controle (CFG). 2.8.4. ANÁLISE DE FLUXO DE DADOS Análise de fluxo de dados (Data Flow Analysis ou DFA) está preocupada em responder perguntas relacionadas a como definições de fluxo devem ser usadas em um programa. É um processo para descobrir as dependências entre as definições e usos (ou referências) das variáveis. A análise de fluxo de dados é inerentemente mais complexa do que a análise de controle de fluxo (Control Flow Analysis ou CFA). Por exemplo, considerando-se que é apenas necessário se utilizar CFA para se detectar a presença de laços, a DFA tem de descrever o que pode acontecer com as variáveis dentro do corpo do laço. Uma das aplicações da análise de fluxo de dados é a detecção de código que nunca é executado de detectação das variáveis que não foram definidas antes de serem utilizadas. Normalmente, a análise de fluxo de dados constrói um gráfico de dependências usado para responder a perguntas relacionadas com o fluxo de dados num programa. Análise de fluxo de dados interprocedural se estende ao gráfico de dependências usado através de limites processuais. Os problemas surgem quando dois parâmetros apontam para o mesmo local de memória, neste caso chamado de um alias. Um alias também pode surgir quando ponteiros são usados. Isso faz com que a DFA para os ponteiros se torne muito complicada. Informações de DFA Interprocedural podem ser representadas em uma versão estendida de um gráfico de chamadas, chamado de gráfico de estrutura. Um refinamento da DFA é a construção de um gráfico de dependência do programa (GDP). Os CDFG foram desenvolvidos por pesquisadores interessados em programas de conversão para rodar em máquinas paralelas. Em um CDFG o fluxo de dados e de controle são ambos representados no mesmo grafo. Esta representação é conveniente em situações que de outro modo exigiriam tanto um DFG e uma CFG. A extensão popular para a CDFG é a de representar a dependência de dados usando a forma estática única de atribuição (FEUA). A FEUA estabelece que cada utilização de uma variável é atingida por exatamente uma definição dessa variável, e que nenhuma variável é definida mais de uma vez. 38 2.8.5. GRAFO DE FLUXO DE CONTROLE E DADOS O Grafo de Fluxo de Controle e Dados (Control Data Flow Graph ou CDFG) é um grafo direto acíclico em que um nó pode ser um nó de operação ou de um nó de controle (representando um ramo, laço, etc.) [6]. As arestas dirigidas em um CDFG representam a transferência de um valor ou controle de um nó para outro. Uma aresta pode ser condicional representando uma condição, como acontece na implementação de uma instrução IF/CASE ou construções de laço. Em geral, os nós de um CDFG podem ser classificados como um dos seguintes tipos [6]: Nós Operacionais: Estes são responsáveis pela aritmética, operações lógicas ou relacionais. Nós chamada: Esses nós denotam chamadas para módulos de subprograma. Nós de controle: Esses nós são responsáveis pelas operações como condicionais e construções de laços. Nós de armazenamento: esses nós representam operações de ligação associadas com as variáveis e sinais. 39 3 REVISÃO DA LITERATURA 3.1 TRABALHOS RELACIONADOS A necessidade de um aumento da produtividade para a concepção de circuitos digitais tem levado à pesquisa em ferramentas de síntese de alto nível para FPGAs. Muitos trabalhos sobre ferramentas e técnicas de síntese de alto nível podem ser encontrados na literatura. Em [40], o compilador Trident open source traduz o código C a uma descrição do circuito de hardware, oferecendo aos designers flexibilidade em supercomputadores de prototipagem reconfiguráveis. O trabalho apresentado em [10] avalia ferramentas de síntese de alto nível para FPGAs. Essas ferramentas têm como entrada uma representação de alto nível de um aplicativo (escrito em C ou MATLAB, por exemplo) e geram uma implementação RTL para um FPGA. Em [12] é descrito LegUp, uma ferramenta que permite técnicas de software a ser usadas para o projeto de hardware e compila automaticamente um programa em C para atingir um software baseado em FPGA híbrido / sistema de hardware. Em [34] a ferramenta CHESS é projetada e desenvolvida para extração de um CDFG e síntese de alto nível de projetos de baixa potência a partir de descrições em nível comportamental VHDL. Outros trabalhos baseados em síntese de alto nível em C / C++ vem ganhando força, a fim de lidar com o aumento da complexidade do projeto. Ferramentas tanto acadêmicas [26], [17] e comerciais [11] [8], foram introduzidas. Algumas técnicas interessantes, métodos, métricas e abordagens para gerar Interface-RTL [32] e os tipos de otimização de Síntese de Alto Nível são explicados em [19][18], [9], [15] e [14]. A maioria das ferramentas e técnicas que empregam HLS focam a otimização na síntese usando VHDL, C / C ++ ou MatLab como entrada e não são adequadas para aplicações específicas de processamento de imagem, então este trabalho apresenta uma nova ferramenta projetada para executar síntese de alto nível para Hardware aplicada a algoritmos de processamento digital de imagem, uma vez que esta ferramenta é capaz de aceitar diferentes linguagens, Java ou SystemVerilog. O trabalho [7] apresenta uma nova linguagem baseada em Java com significantes extensões chamada Lime, o que é diferente do SynMaker que não é uma linguagem e sim uma ferramenta que aceita código Java, portanto não existe a necessidade de conversão de semântica para poder utilizar o SynMaker. O Lime apresenta no trabalho [7] experimentos de conversão de espaço de cores, o que é feito automaticamente pelo modelo base utilizado no SynMaker. No trabalho foi mostrado experimentos com imagem, os experimentos utilizados no SynMaker são experimentos realizados em vídeo. 3.2 FERRAMENTAS DE SÍNTESE DE ALTO NÍVEL Nesta seção serão apresentadas, de forma resumida, algumas ferramentas de síntese de alto nível que já estão em uso no meio acadêmico ou no mercado profissional. 40 3.2.1. SYSTEMC SystemC é uma biblioteca de classes C++ que pode ser utilizada em conjunto com uma metodologia para a criação de um modelo de ciclo de precisão dos algoritmos de software, arquitetura de hardware, e interfaces de SoC (System On a Chip) e projetos de nível de sistema.Uma das principais características de SystemC é que ela pode ser utilizada em conjunto com ferramentas de desenvolvimento padrão C++ para se criar um modelo de nível de sistema, simular rapidamente para validar e otimizar o design, explorar vários algoritmos, e fornecer a equipe de desenvolvimento de hardware e software uma especificação executável do sistema. Uma especificação executável é, essencialmente, um programa em C++ que apresenta o mesmo comportamento que o sistema quando executado. A biblioteca de classes SystemC fornece as construções necessárias para a modelagem da arquitetura do sistema, incluindo tempo de hardware, paralelismo e comportamento reativo que são inexistentes no C++ padrão. A adição dessas construções na linguagem C exigiria extensões proprietárias para a linguagem, o que não é uma solução aceitável para a indústria. Desta forma a linguagem de programação orientada a objetos C++ oferece a possibilidade de estendê-la através de classes, sem a adição de novas construções sintáticas. A biblioteca SystemC provê essas classes e permite que os designers continuem a usar o familiar C++ e ferramentas de desenvolvimento. SystemC suporta hardware/software co-design e a descrição da arquitetura de sistemas complexos que consistem em componentes de hardware e software. Ele suporta a descrição de hardware, software e interfaces em um ambiente C++. As seguintes características do SystemC versão 2.0 permitem que seja usado como um idioma codesign: • Módulos: SystemC tem uma noção de uma classe recipiente chamado de módulo. Este é uma entidade hierárquica, que pode ter outros módulos ou processos nela contidas. • Processos: Processos são usados para descrever a funcionalidade. Processos estão contidos dentro de módulos. SystemC oferece três abstrações processo diferente de serem utilizado pelo hardware e desenvolvedores de software. • Portas: Módulos têm portas através das quais eles se conectam a outros módulos. SystemC suporta portas única direção e bidirecional. • Sinais: SystemC suporta sinais resolvidos e não resolvidos. Os sinais resolvidos podem ter mais de um driver (one bus), enquanto os sinais não resolvidos só podem ter um driver. • Rico conjunto de tipos de portas e sinal: Para apoiar a modelagem em diferentes níveis de abstração, a partir do funcional para a RTL, SystemC suporta um rico conjunto de porta e tipos de sinais. Isso é diferente de linguagens como Verilog que só suportam bits e bit-vetores como porta e tipos de sinais. SystemC suporta os tipos de sinais dois valores e de quatro valores. • Rico conjunto de tipos de dados: SystemC possui um conjunto de tipos de dados para suportar múltiplos domínios de design e níveis de abstração. Os tipos de dados de precisão fixa permitem simulação rápida, os tipos de precisão arbitrária podem ser utilizados para cálculos com grandes números e os tipos de dados de ponto fixo podem ser utilizados para aplicações de DSP. SystemC suporta tanto dois valores quanto quatro valores de tipos de dados. Não há limitações de tamanho para tipos SystemC de precisão arbitrária. 41 • Clocks: SystemC tem a noção de relógios (como sinais especiais). Relógios são a cronometristas do sistema durante a simulação. Vários relógios, com arbitrária relação de fase, são suportados. • Ciclo de simulação: SystemC inclui um ciclo ultraleve baseado em núcleo de simulação, que permite a simulação de alta velocidade. • Vários níveis de abstração: SystemC suporta modelos de duração indeterminada em diferentes níveis de abstração, variando de modelos funcionais de alto nível para modelos de ciclo de relógio precisos de modelos RTL. Ele suporta refinamento iterativo de modelos de alto nível em níveis mais baixos de abstração. • Protocolos de comunicação: SystemC permite a comunicação semântica multinível que permitem descrever os protocolos do sistema I/O e SoC com diferentes níveis de abstração. • Suporte a depuração: classes SystemC tem verificação de erros em tempo de execução, que pode ser ligado com uma flag de compilação. • Forma de onda rastreamento: SystemC suporta rastreamento de formas de onda em VCD, WIF, e Formatos ISDB. A metodologia de projeto de hardware baseada em SystemC é mostrada na Figura 18, abaixo: Figura 18. Metodologia de projeto de hardware SystemC. Esta técnica tem uma série de vantagens. Com a abordagem SystemC, o projeto não é convertido de uma descrição em C em uma descrição sintetizavel HDL com um grande esforço. O projeto é lentamente refinado em pequenas seções para adição do hardware e o tempo de construção necessário para produzir um bom design. Usando esta metodologia de refinamento, fica mais fácil de implementar mudanças de projeto e detectar erros durante refinamento. Usando a abordagem SystemC, o designer não precisa ser um especialista em múltiplas linguagens. SystemC permite a modelagem do nível do sistema até RTL, se necessário. A abordagem SystemC proporciona maior produtividade, porque o designer pode modelar a um nível mais elevado. Escrevendo a um nível mais elevado pode 42 resultar em menor código, que é mais fácil de escrever e simula mais rápido do que ambientes de modelagem tradicionais. Embora a versão atual do SystemC não tenha as construções adequadas aos modelos RTOS, isto está sendo previsto para versões futuras. Isso vai permitir que um refinamento semelhante baseado na metodologia de concepção para as partes do sistema de software. Os projetistas de software irá colher benefícios semelhantes aos projetistas de hardware. Seguindo esta mesma linha de vantagens foi desenvolvido nesse mestrado o SynMaker que além de aceitar código de entrada puramente Java é especifico para aplicações de filtro de processamento de imagem e o resultado da sua síntese funcionando em tempo real numa placa de prototipação. 3.2.2. CATAPULT C A ferramenta de síntese CatapultC faz com que projetistas de hardware trabalhem num nível de abstração mais produtivo, possibilitando maior eficiência na produção de projetos de hardware ASIC / FPGA mais complexo que são necessários em aplicações modernas. Ao sintetizar a partir de especificações na forma de ANSI C++, desenvolvedores de hardware podem utilizar um processo preciso e repetitivo para criar hardware muito mais rápido do que com métodos convencionais manuais. O resultado é um fluxo livre de erros, que produz descrições RTL precisas sintonizados para a tecnologia alvo [11]. Reconhecendo essa necessidade insatisfeita para melhorar a produtividade e aprendizagem a partir da deficiência de tentativas iniciais, a Mentor Graphics definiu uma nova abordagem para a síntese de alto nível baseada em ANSI C++ puro. Além da tecnologia de síntese em si, ficou claro que a linguagem de entrada desempenhou um papel fundamental no fluxo e muita ênfase foi colocada sobre este aspecto. As desvantagens de linguagens estruturais, tais como VHDL, SystemVerilog ou mesmo SystemC utilizados na primeira geração de ferramentas são inúmeras: Eles são estranhos à maioria dos desenvolvedores de algoritmo. Eles não elevam suficientemente o nível de abstração. Eles podem vir a ser extremamente difíceis escrever. A American National Standards Institute (ANSI), C++ é provavelmente a mais amplamente utilizada linguagem de design no mundo. Ela incorpora todos os elementos para o modelo de algoritmos de maneira concisa, clara e eficiente. Uma biblioteca de classes pode ser usada para comportamento do modelo pouco precisas. Além disso, C++ possui muitos projetos e ferramentas de depuração que podem ser reutilizados para o projeto de hardware. Com muitos desenvolvedores de algoritmos trabalhando em puro C/C++, a realização de síntese de alto nível é vista com bons olhos pelas empresas para alavancar empreendimentos existentes, pois estas podem aproveitar a modelagem do sistema abstrato sem ensinar cada designer uma nova linguagem. Em comparação com a primeira geração de ferramentas comportamentais, CatapultC propõe uma abordagem onde temporização e paralelismo são removidos da linguagem fonte sintetizada. Esta é uma diferença fundamental com ferramentas com base nas linguagens estruturais, o que exige algumas formas de construções de 43 hardware. A flexibilidade e facilidade de uso oferecida pela síntese de ANSI C++ puro e o estilo intuitivo de síntese do CatapultC é um aspecto fundamental deste fluxo. 3.2.3. IMPULSE C ImpulseC não é uma nova linguagem de programação, mas uma ferramenta de síntese de alto nível baseada no padrão ANSI C para programação em FPGA de aplicações embarcadas e de Computação de Alto Desempenho (High Performance Computing ou HPC) com suporte para ferramentas de desenvolvimento padrão C e multi-processo de particionamento. ImpuseC inclui um compilador software-tohardware que otimiza código C para paralelismo gerando HDL pronto para síntese tendo como alvo FPGA, também gerando a interface hardware/software. O ImpulseC tem como objetivo descrever aceleradores de hardware usando C e transformar funções de computação intensiva para FPGAs, é usado para criar paralelismo e fluxo de dados orientados a aplicações, ideal para DSP, processamento de imagem e muitos outros domínios de aplicação, com ou sem um processador embutido. Para programadores C, o ImpulseC dá acesso a FPGAs, permitindo o uso de ferramentas padrão C, inclusive depuradores, facilita a criação e controle de paralelismo em todos os níveis. Permite que desenvolvedores implementem C-statements ou grandes blocos de statements, dentro de laços, incluindo laços de pipeline. Proporciona suporte a particionamento hardware e software, em plataformas baseadas em FPGA, mas não apenas o FPGA e permitir que o compilador seja estendido através de scripts. A Figura 19 demonstra o fluxo básico de projeto implementado pela ferramenta de síntese de alto nível ImpulseC: Aplicações em linguagem C: são utilizadas ferramentas padrão C e métodos de programação para acelerar suas aplicações embutidas, em estação de trabalho e servidor. Perfil e partição: entre o processador e o acelerador FPGA, usa-se vários processos em paralelo para aumentar o desempenho. Verificar e depurar: usando ferramentas de desenvolvimento em linguagem-C, usa-se o Monitor de Aplicação Impulse para analisar o fluxo de dados em paralelo. Compilar e otimizar: uso interativo de ferramentas gráficas e paralelizar automaticamente e utilizar pipeline no seu código C crítico. Gerar automaticamente hardware FPGA: geração automática pronta para uso na plataforma FPGA selecionada. Gerar automaticamente interfaces de host-FPGA: geração automática de interface para a plataforma selecionada. Inclui-se no Impulse-C um pré-processador C (gcc), C parser/compilador (incluindo otimizações comuns do compilador, sub-expressões comuns), otimizador de paralelismo (incluindo instrução pipeline e agendamento), gerador Hardware (VHDL ou Verilog), suporte extensível para pacotes de plataformas (Para plataformas baseadas em FPGA). Totalmente compatível com ferramentas de desenvolvimento padrão C, depuradores de nível C para testes e verificação Profilers, ferramentas de gerenciamento de configuração e não altera significativamente o fluxo de projeto existente. O Impulse C promete para o usuário as vantagens no desenvolvimento de aplicações, sendo mais ágil, tendo time-to-protótipo mais rápido e risco reduzido, mais 44 oportunidades para otimização do projeto e experimentação, assim reduzindo o custos do projeto, das fases de alto risco de projeto de hardware, estas são características e vantagens que em geral são aplicadas as ferramentas de sínteses. Apesar de o Impulse C proporcionar uma gama de vantagens para o usuário, o mesmo não oferece suporte a paradigma de orientação ao objeto, o que o SynMaker na sua primeira versão já é capaz de fazer com algumas restrições. Figura 19. Fluxo básico do Impulse C. 3.2.4. ANÁLISE COMPARATIVA Nesta seção é feito um resumo comparativo entre as ferramentas estudadas antes do desenvolvimento do SynMaker. Após pequisas realizadas nas diversas ferramentas presente no meio acadêmico e profissional foi verificado que há uma falta de metodologia e ferramentas para programadores de software mais familiarizados com o Java para projetar para uma plataforma de hardware, além de os designers que utilizam SystemVerilog serem obrigados a trabalhar no nível RTL para realizar síntese, aumentando o seu esforço de projeto, tempo e erros. Das ferramentas que estão indicadas na Tabela 4, apenas o Lime aceita como input linguagem Java, a maioria das 45 ferramentas utilizam linguagem C e, apenas apenas, Catapult C e System C dão suporte linguagem C++ que tem funcionalidades de orientação ao objeto objeto,, o que difere da ferramenta proposta, proposta, pois, a mesma foi desenvolvida para suporta mú múltiplas ltiplas linguagens, li apesar do SynMaker, na versão atual, ter seu foco de desenvolvimento voltado mais para a linguagem JAVA. Ainda observando a Tabela 4,, verifi verifica-se se que muitas ferramentas conseguem ou tem aplicabilidade para algoritmos de processamento de imagem, porém nenhuma das citadas conseguem fazer uma síntese e integrar automáticamente com uma placa de prototipação especí específica,, que no caso do SynMaker é a plataforma de camera digital da Altera. Uma observação importante é que a ferramenta Lime que na teoria faz um processo parecido com a ferramenta proposta, na prática não funciona para videos, videos apenas para imagens e com algoritmos muito simples de conversão de cores. Tabela 4. Comparação mparação entre ferramentas de síntese. 46 4 FERRAMENTA DE SÍNTESE: SYNMAKER Neste capítulo será explicada por completo a ferramenta desenvolvida para esta dissertação, como funciona, como deve ser instalada, como foi desenvolvida, as liguagens, restrições, metodologia e fluxo de síntese. O SynMaker proporciona que os projetistas trabalhem num ambiente de abstração mais produtivo, fazendo com que circuitos, antes complexos, se tornem mas fáceis de serem desenvolvidos. Em especial, no caso do SynMaker, aplicações de filtro de processamento de imagens. A ferramenta também é capaz de criar vários tipos de implementações diferentes para uma mesma aplicação, assim proporcionando ao projetista a opção de escolha da melhor solução para as restrições (de área, potência) especificadas para o sistema. Tendo em vista que a maioria das ferramentas de síntese de alto nível existentes no mercado utilizam liguagem C ou C++ e conceitos estruturais, percebeu-se que falta na comunidade científica uma ferramenta que utilizasse a linguagem Java (uma das linguagens mais difundidas no mundo) para realização de síntese de alto nivel. Foi pensando em preencher esse espaço que o SynMaker foi desenvolvido. Além de Java, o SynMaker é suficentemente flexível para aceitar outras linguagens de entrada e produzir o mesmo resultado de síntese, essa flexibilidade é um diferencial da ferramenta em relação a outras existentes no mercado. O SynMaker foi construído utilizando linguagem de programação Java e usa a biblioteca para console chamada enigma para instanciar um console e mostrar para o usuário informações sobre o processamento, usa o framework log4j para extrair um log e para exibir a simulação do código de processamento de imagem de entrada inicial é utilizada API JAI quando for utilizado uma imagem na simulação e a API XUGGLER quando for utilizado um vídeo. Para iniciar a síntese, o usuário precisa ter um projeto SynMaker, o projeto SynMaker tem arquivos e pastas padrão que se não forem detectados a ferramenta irá lançar uma exceção. Essas configurações padrão são: a pasta Sourcer (contém o código-fonte do projeto base da plataforma FPGA), pasta Log (contém o registro de síntese), pasta de Simulação (contém as imagens e arquivos para serem utilizadas no processo de simulação e que foram geradas neste processo) e pasta de Otimização (contém um arquivo CDFG para gerar o gráfico CDFG e fazer analisadores de otimização). A descrição RTL gerada no final da síntese é um SystemVerilog, que, agora, pode ser sintetizado por uma ferramenta CAE, como o QUARTUS II, e pode ser utilizado ou não num projeto base da plataforma D2-70 da Altera, como explicado na secção 4.1 . A Figura 20 ilustra a visão global da ferramenta desenvolvida, iniciando o processo, como já foi citado, com uma descrição comportamental de entrada, JAVA ou SystemVerilog, logo após o SynMaker pode realizar uma simulação ou uma síntese nesse arquivo que foi dado de entrada, onde o resultado da simulação será apresentado no computador e o resultado da síntese será um conjunto de módulos RTL que formarão um projeto que poderá ser compilado e executado na placa de prototipação que exibirá o resultado. 47 Figura 20.. Visão global do funcionamento. funcionamento 4.1 ARQUITETURA ARQUITET A ALVO DO SYNMAKER A ferramenta proposta se destina ao mapeamento automático de Java ou SystemVerilog orientado ao objeto para uma plataforma FPGA. Para alcançar este objetivo, a plataforma de destino é a Plataforma de Desenvolvimento Terasic Câmera Digital. Este kit contém um Altera DE2 DE2-70 70 Board (DE2 (DE2-70), 70), módulo da câmera digital (D5M) de 5 Mega Pixel, Pixel, 4,3 "LCD Touch Panel Kit (LTM). A Placa de desenvolvimento e educacional DE2 DE2-70 70 é equipada com quase 70.000 LEs da Altera Cyclone II 2C70, esta placa oferece um rico conjunto de recursos para o desenvolvimento de sistemas digitais sofisticados sofisticados. A D5M é equipada com um sensor Micron de 5 mega pixel pixels CMOS, suporta 2592H x 1944V pixels ativos com dados de saída em formato RGB padrão adrão Bayer e têm uma taxa de quadros total com resolução de até 15 quadros por segundo (FPS). O LTM oferece aos usuários um resolução de 800x480 em cores de alta qualidade LCD Touch Panel. A abordagem proposta faz uso de uma plataforma base que contém um conjunto de módulos que não são sintetizados pela ferramenta. Estes módulos são responsáveis por receber recebe os pixels da câmera D5M e exibe no LTM. Os principais elementos da plataforma são: são CDD_Capture (responsável por con controlar trolar sensores CCDs da câmera). RAW2RGB (converte o pixe pixell cru capturado no formato RGB). Sdram_Control_4Port Sdram_Control_4Port (controlador de memória). Touch_Tcon con (controle de tempo e dados de imagem de saída de SDRAM) LTM (display no painel de toque). A Figura 21.a mostra uma parte do projeto base com componentes (Touch_Tcon Touch_Tcon e LTM) que não são sintetizados sintetizados pelo SynMaker. A arquite arquitetura tura final, após a síntese, é obtida através da inserção inserção, na plataforma base base, dos os componentes sintetizados pela ferramenta, ferramenta, este estes podem ser visto na Figura 21.b .b onde os módulos com nome de principal e TestSobel são sintetizado e ligados aos módulos Touch_Tcon e LTM da 48 plataforma de base. No estado atual, o SynMaker apenas pode alterar o fluxo do projeto base entre a Touch_Tcon e LTM, mas o objetivo é que, no futuro, a ferramenta consiga alterar o fluxo do projeto em outras partes, assim sendo possível usar outros módulos da plataforma base. (a) (b) Figura 21. Visão RTL de parte do projeto base utilizado pelo SynMaker. (a) Projeto base padrão. (b) Projeto Base alterado pelo SynMaker após a síntese. 4.2 FLUXO E MODELAGEM DO SISTEMA A Figura 22, ilustra o fluxo detalhado de síntese realizada pelo SynMaker. O SynMaker utiliza uma metodologia de síntese para gerar automaticamente os pinos de interfaces software-hardware e processar código de linguagem de alto nível, freqüentemente representado por sintaxe e semântica da linguagem, em descrições de hardware Verilog equivalentes. Depois, o SynMaker usa uma compilação específica para plataformas baseadas em FPGA, no caso, é a Altera DE2-70 Plataforma de Desenvolvimento de Câmara Digital. O SynMaker aceita como entrada para síntese apenas código na linguagem Java ou SystemVerilog (não sintetizável pelo Quartus, com paradigma de orientação ao objeto), a arquitetura foi planejada para que no futuro possa ser possível usar outras linguagens como entrada. Após receber a entrada há um interpretador de comandos para saber qual será o próximo passo da ferramenta, então depois, caso o comando interpretado seja um comando para realizar uma simulação ou síntese, a ferramenta usa um pré-compilador. O pré-compilador carrega os arquivos da biblioteca da ferramenta que serão necessárias para fazer a síntese e separam as entradas, as entradas de diferentes linguagens seguiram caminhos diferentes e mais tarde serão transformadas em uma representação intermediária única. O pré-compilador vai pegar a descrição 49 comportamental e irá utilizar um parser para a linguagem específica, no caso de Java, usamos um parser já existente, mas no caso de SystemVerilog foi desenvolvido um parser para estaa linguagem baseado na definição SystemVerilog Formal (BNF) que está presente em [36]. A análise gera uma Árvore Sintática Abstrata (AST) e esta AST é transfomada em uma representação intermediária criada para o SynMaker chamado Árvore Sintática Abstrata Genérica (GAST). Assim, pode-se converter AST de diferentes línguas em uma única representação e continuar o fluxo. Esta representação única serve como entrada tanto para fase de simulação quanto para fase de síntese da ferramenta. Se o usuário escolher através de comando realizar uma simulação, o SynMaker irá para fase de simulação depois da realização da pré-compilação, caso ele escolha realizar síntese, o SynMaker irá para fase de síntese após a pré-compilação. Na fase de simulação de alto nível o SynMaker verifica, antes de fazer uma síntese, se o código de entrada é um aplicativo de processamento de imagem digital válido e exibi a execução desse código em tempo real na tela. Quando o usuário escolhe fazer a síntese, o compilador HLS irá decidir o que vai ser feito com o GAST e pode começar a síntese de duas formas que é escolhida pelo usuário através de um parâmetro no comando dado na fase de processamento de comando no início do processo. O primeiro caminho o SynMaker faz um processo de síntese simples, sem otimização, usa apenas a representação intermediária GAST para fazer algumas análises e gerar vários objetos chamados de entidades que serão transformados em RTLs pelo gerador no próximo passo. O segundo caminho o SynMaker faz um processo de síntese mais complexa e utiliza algumas técnicas de otimização para isso. Nesse processo a parte da GAST equivalente a uma função é transformada em uma representação intermediária CDFG pelo CDFG Builder. Logo após, um arquivo contendo essa representação em forma gráfica também é criado e este arquivo pode ser visualizado pelo o usuário. E por fim, as técnicas de otimização é aplicada para esta versão da ferramenta, apenas, as otimizações ALAP, ASAP e IRM, podem ser feitas, o resultado final é transformado em um RTL no próximo processo chamado Gerador RTL. O Gerador RTL produz arquivos SystemVerilog que podem ser sintetizáveis, o RTL é sintetizado para uma implementação FPGA utilizando a ferramenta comercial Quartus II para compilar para uma Placa, no nosso caso, a plataforma de desenvolvimento de câmera digital DE2-70 da Altera. O SynMaker usa um script TCL para criar um projeto Quartus e executar os seguintes comandos: Quartus_map - Traduz arquivos de concepção do projeto (por exemplo, a RTL ou netlist EDA), elementos de design e mapeamento dos recursos do dispositivo. Quartus_fit - Denomina os lugares e rotas dos recursos do dispositivo FPGA. Quartus_sta - Realiza uma análise de tempo estático no design. Quartus_asm - Gera o arquivo de programação de pós-local e rota-design. No fim da síntese o RTL é transformado numa implementação FPGA completa sob a forma de um fluxo de bits para a programação da plataforma FPGA alvo. 50 Figura 22. Fluxograma de síntese do SynMaker. 4.2.1. DESCRIÇÃO COMPORTAMENTAL O primeiro passo no fluxo representa a entrada inicial da ferramenta, que para esta versão do SynMaker é um código de descrição comportamental Java ou SystemVerilog (não sintetizável pelo Quartus, com algumas características de paradigma de orientação a objeto), a arquitetura foi planejada para que no futuro possa ser possível usar outras linguagens como entrada. O código de entrada apresenta algumas restrições para que possa ser sintetizado pela ferramenta, se por acaso algumas dessas restrições não forem seguidas, a ferramenta lançará uma exceção. O código não pode apresentar o uso de polimorfismo ou herança. As classes devem sempre estender a um tipo HLSSystem, HLSSynth ou HLSNoSynth. HLSSystem se for a classe que será sintetizada para representar o módulo TopLevel do sistema. HLSSynth se for uma classe para ser sintetizada pela ferramenta. HLSNoSynth se for uma classe que faz parte da biblioteca da ferramenta que representar algum módulo já existente do projeto base. 51 Sempre deve existir uma classe que estende HLSSystem. Não pode existir mais do que uma classe que estende HLSSystem, deve sempre haver um método run() na classe que estende HLSSystem, esse método não terá processamento, apenas chamada de função, e o designer deve estar ciente que este metodo é uma representação abstrata de um loop infinito no processo de síntese. Algumas operações da linguagem ainda não são sintetizadas como Switch, While, Do-While, break, continue e construtores que representam o estado inicial de uma classe. Algumas expressões da linguagem também ainda não são possíveis de serem utilizadas no código de entrada para o SynMaker como expressão condicional ternária. 4.2.2. PROCESSADOR DE COMANDOS DE SÍNTESE O processador de comandos de síntese é onde a ferramenta decide através do comando passado pelo usuário qual o caminho que vai seguir, o SynMaker pode fazer uma simulação de alto nível para verificar a funcionalidade do código de entrada, antes de fazer uma síntese, o código de entrada exibe na tela do PC o mesmo comportamento que seria exibido na placa de prototipação, ou o usuário pode escolher fazer uma síntese, então a ferramenta vai seguir os próximos passos. Ao executar a ferramenta o usuário deve usar um desses comandos com os parâmetros, explicados abaixo, para fazer alguma ação: 1. sm_create [pasta] - Use para criar um projeto de SynMaker. O Parâmetro pasta é o caminho onde será criada a pasta do projeto. Exemplo: “sm_create C:\Users\Luis\Desktop\projesynmaker\”. 2. sm_simu [-v Video | -i imagem ] [arquivo] - Use para fazer uma simulação. O parâmetro arquivo é o caminho do código a ser simulado. O parâmetro –v é para realizar uma simulação com exibição de vídeo passando o vídeo que será simulado e o parâmetro -i para simulação de imagem passando a imagem a ser simulada. Exemplo: “sm_simu -v C:\Users\luis\Desktop\projesynmaker\SimulationFiles\video.avi C:\Users\luis\Desktop\projesynmaker\TestSobel3.java ”. 3. sm_synth [-s] | [-o tipo] [-g |-c |-p] [arquivo] - Use para fazer um processo de síntese. Os parâmetros s, o, g, c,p e arquivo são, respectivamente, realizar uma síntese simples, realizar um síntese com uma otimização que pode ser do tipo ALAP, ASAP ou IRM, gerar um projeto Quartus, executar uma compilação Quartus com a RTL gerado, realizar a programação da placa com o arquivo .sof gerado pela compilação do Quartus e o parâmetro final “arquivo” é o caminho do código a ser sintetizado. Exemplo: “sm_synth -scp C:\Users\luis\Desktop\projesynmaker\TestSobel3.java”. 52 4.2.3. PRÉ-COMPILADOR PRÉ COMPILADOR HLS Antes de processar um comando de simulação ou síntese há uma etapa chamada de préé-compilação compilação. O pré-compil compilador é responsável por transformar ooss códigos de entrada para o SynM SynMaker na representação intermediária intermediá genérica,, para isso o SynMaker carrega oss arquivos de entrada vindo vindos da biblioteca ca de síntese de alto nível que são as classes que quando quando sintetizadas representarão módulos do projeto base, módulos ódulos não sintetizáveis e oss arquivos de entrada do usuário que podem ser de diferentes linguagen e que passarão por um Parser específico. linguagens, especí Nesta etapa a ferramenta separa as entradas que podem ser de diferentes linguagens e,, portanto seguiram caminhos diferentes, porém no final ess essas as entradas serão transformadas eem uma representação intermediária intermediária única.. A descrição comportamental vai passar através de uma parser específico para cada linguagem, linguagem no caso de Java, usou-se usou um parser que já exist existe,, mas no caso de SystemVerilog foi desenvolvido um parser para a linguagem baseado na definição System desenvolvido SystemVerilog Verilog Formal F (BNF) que está presente em [36]. [36]. A análise gera uma Á Árvore Sintática intática Abstrata bstrata (AST) e esta AST é convertida para uma representação intermediária criada para o S SynMaker chamada Árvore Sintática S Abstrata bstrata Genéric enérica (GAST). Assim, poderia converter AST de linguagens diferentes em uma única representação e continuar o fluxo. Esta representação única única serve como entrada para a etapa de simulação ou de síntese de alto nível, Compilador ompilador HLS HLS. A Figura 23 demonstra o fluxo detalhado da obtenção da representação presentação intermediaria GAST, apartir de uma linguagem de entrada. Figura 23.. Fluxo de pré-compilação compilação d doo SynMaker. SynMaker 4.2.4. SIMULAÇÃO O SynMaker proporciona ao usuário dois tipos de simulaç simulação, ão, a primeira o código digo de entrada que será sintetizado é simulado utilizando uma imagem que também é dada de entrada pelo usuário e a segunda maneira o código de entrada é simulado utilizando um vídeo. A ferramenta exibe a simulação em tempo real do código e para isso ambos os tipos de simulação seguem as seguintes etapas: a geração da classe de simulação SynMaker, esta é uma classe padrão que será responsável por pegar os pixels 53 da imagem ou vídeo de entrada dada pelo o usuário. Essa classe é gerada com alteração na sua composição para que os pixels sejam alterados de acordo com o que o código a ser sintetizado executará. Algumas alterações são feitas no código da classe que estende HLSSsystem, seu package é removido e é acrescentado o import da biblioteca de simulação. Logo após as classes citadas são compiladas, para simulação de vídeo é necessário a simulationlib, a biblioteca em Java de manipulação de vídeo chamada de xuggler e para imagem é necessária a biblioteca de manipulação de imagem chamada de JAI. A classe de simulação SynMaker é executada usando a maquina virtual Java e depois o SynMaker exibe os resultados que foram gerados por essa execução, Figura 24. (a) (b) Figura 24. Tela de Simulação. (a) Vídeo de entrada. (b) Vídeo de saída. 4.2.5. COMPILADOR HLS O compilador HLS irá decidir o que vai ser feito com o GAST e pode começar a síntese de duas formas, escolhida pelo usuário através de um parâmetro determinado no início do processo. O primeiro caminho a SynMaker faz um processo de síntese simples, sem otimização, usa apenas a representação intermediária GAST para fazer algumas análises e gerar os objetos entidades que serão transformados em um RTL pelo gerador RTL no próximo passo. O segundo caminho o SynMaker faz um processo de síntese mais complexa e utilizar algumas técnicas de otimização para isso, a Figura 25 mostra como este processo foi feito. A parte da GAST que representa uma função é utilizada neste processo, essa parte da GAST é transformada em uma representação chamada CDFG no passo CDFG Builder. Na próxima etapa, um arquivo contendo o gráfico CDFG é criado e pode ser visualizado pelo usuário, este arquivo é levado para o passo seguinte. O último passo do fluxo de otimização é o Ignition optimization que implementará algumas técnicas de otimização, nesta versão inicial apenas otimização de schedule como ALAP, ASAP e IRM, podem ser feitas e, finalmente, o resultado é transformado em um RTL no próximo processo chamado gerador RTL. 54 Figura 25. Fluxo de otimização. 4.2.6. SÍNTESE DE ALTO NÍVEL O projeto básico da plataforma de desenvolvimento de Câmera Digital da Altera foi comentada na seção 4.1 , esse projeto básico funciona em um processo monociclo, isto significa que em cada ciclo de clock do projeto acontece a captura de um pixel pela câmera CCD, com base nesta perspectiva desenvolveu-se uma metodologia simples de síntese para este ambiente. Quando o usuário escolher uma síntese HLS simples a ferramenta irá fazer uma síntese com um clock único e fixo, que é usado no projeto base da plataforma da Altera de Desenvolvimento de câmera digital, portanto, não irá gerar uma máquina de estado finito ou scheduling, alocação ou otimização de ligação. Neste tipo de síntese é usada apenas a representação intermédia GAST que é analisada e transformada em RTL. A metodologia de síntese criada é simpes: uma classe de linguagem de alto nível será sintetizada em um módulo principal e as funções desta classe serão sintetizadas em módulos que irão ser instanciada dentro do módulo principal sintetizado, se houver uma instância da classe em uma função ou em uma classe, o módulo que representa esta classe é instanciado em um módulo que será sintetizado para aquela função ou classe. Para o módulo sintetizado, apartir de uma função de uma linguagem de alto nível, os parâmetros da função serão sintetizados em pinos de entrada do módulo e o retorno da função em um pino saída, o corpo da função será sintetizado em uma função comum do Sistema Verilog, a função que foi gerada é chamada em um bloco combinacional e o resultado é colocado em um registrador, um bloco seqüêncial é criado e dentro dele o registrador criado no bloco combinacional é ligado a um sinal de saída do bloco seqüêncial em cada pulso de clock, por fim, um link é criado para ligar o sinal de saída do bloco seqüêncial para a saída do módulo, ver Figura 26. Para o módulo sintetizado que veio de uma classe de uma linguagem de alto nível, os parâmetros das funções internas serão sintetizados em pinos de entrada do módulo e o retorno das funções internas em pinos de saída, se tem uma instância de objeto nesta classe, a ferramenta vai sintetizar a instância do módulo que foi sintetizado para a classe desse objeto e os pinos desse módulo instanciado serão instanciados e ligados ao módulo que está sendo sintetizado, da forma que para cada pino de saída que for do módulo instanciados será criado e ligado um pino de entrada no módulo sintetizado e para cada pino de entrada que for do módulo instanciados será criado e ligado um pino de saída do módulo sintetizado, não existe um bloco combinacional ou seqüencial (ver Anexo II). Chamada de função será sintetizada em links tanto na síntese de classe como na de função ligando entradas e saídas de diferentes módulos, para isso existem algumas restrições para sintetização de ligações, para evitar que dois pinos de saída sejam ligados a um mesmo pino de entrada, por exemplo. Variáveis Globais da classe serão sintetizadas em registradores internos para cada módulo que será gerado devido a cada função da classe, esses registradores serão conectados ao registrador global que os gerou no modulo pai. Vetores de deslocamento de pixel serão sintetizados 55 dentro do bloco seqüencial. Seguindo essa lógica, a Figura 26, demostra um exemplo de código SystemVerilog gerado pela síntese de alto nível feita pelo SynMaker, com seus inputs, outputs, declarações, ligações, lógica seqüêncial e combinacional. Figura 26. Exemplo de código SystemVerilog gerado pela síntese. A Figura 27, mostra um exemplo da metodologia de síntese para classe, função e a criação das respectivas interfaces. No exemplo a descrição comportamental dada como entrada contém um classe que extende HLSSynth, com duas funções internas, a classe será sintetizada em um módulo chamado Sobel e cada função desta classe será sintetizada em outros dois módulos chamados Sobelfsobel e Sobelsinal_cor que ficaram internos ao módulo Sobel. As interfaces são sintetizadas de acordo com a quantidade de parâmetros de entrada em cada função, retorno da função, declarações da classe e mais dois pinos padrões para representar o clock e a reset, no caso da Figura 27, por exemplo, o código de entrada possui uma função sinal_cor com um parâmetro de entrada int d e um retorno res, o SynMaker irá sintetizar uma interface de entrada com nome Sobelsinal_input_1 para representar a entrada relativa ao parâmetro int d e uma de saída com o nome de Sobelsinal_cor_Output_1 para representar o return res, além de sintetizar também por padrão o Sobelsinal_corIclk e o Sobelsinal_corIRST que representam, respectivamente, o clock e o sinal de reset. Se existir uma instanciação de classe dentro da função ou de outra classe, o módulo que representa essa classe também será instanciada internamente no módulo que esta sendo sintetizado e seus pinos serão sintetizados no módulo que esta sendo sintetizado e interligados. 56 Figura 27.. Metodologia de síntese do SynMaker para classe, função e sua respectiva interface RTL. A Figura 28, 28, ilustra uma visão geral da metodologia de síntese da ferramenta, destacando a classe TestSobel que extende HLSsystem que dará origem ao módulo Toplevel da síntese. Cada trecho destacado no ccódigo ódigo será sintetizado no respectivo item que pode ser diferenciado pelas cores na figura. O código comportamental de entrada contém a instanciação de duas classes não sintetizáveis destacadas pela cor amarela, estas vão dar origem a dois módulos, LTM e TCON. TC Já o trecho de código destacado de verde escuro que contém a instanciação de uma classe sintetizável pela ferramenta chamada Sobel irá gerar um módulo com nome Sobel. As linhas roxas, roxas vermelho, laranja e verde claro que representam a síntese de ligação foram geradas a partir das chamadas de função do código de entrada, por exemplo, iLCD_R_t = tcon.getNextPixelR() tcon.getNextPixelR( deu origem a ligação entre o módulo TestSobelRun e Tcon. Tcon E por fim, o destaque da função obrigató obrigatória ria run() que está em azul será sintetizada em outro módulo chamado TestSobelRun. Quando o usuário escolhe a síntese com otimização uma metodologia diferente é iniciada. Para esta versão só há possibilidade de ser feita otimização por scheduling ASAP, ALAP e IRM, ASAP, IRM, esse tipo de síntese não suporta, suporta ainda,, aplicações na Plataforma de Processamento de Imagem Digital da Altera. No início da síntese com otimização ocorre uma transformação do GAST num CDFG. IIgual gual à metodologia simples, uma classe de linguagem de alto nível ainda sserá sintetizada sintetizad em um módulo principal e as funções desta classe ainda ser serão ão sintetizadas em módulos módulo que irão ser instanciados dentro do módulo principal sintetizado. A diferença é que o compilador da ferramenta irá separar a parte da GAST que representa representam as funções e extrair um CDFG para cada função desta, ou seja, para cada função que existir na GAST irá ser gerado um CDFG. A otimização será feita apenas nas funções porque são sã nelas que vão estar presentes as funcionalidade Após obter o CDFG da função funcionalidades. função, a otimização escolhida pelo usuário é feita e a ferramenta gera a descrição RTL, uma máquina de estado finito e um caminho de dados. As classes serão sintetizadas como módulos pais que apresentam em sua estrutura, basicamente, apenas instanciação de outr outros os módulos e links, não existe existem funcionalidade, portanto, não é feita nenhuma otimização, então, nenhuma extração de funcionalidade, CDFG é feita. 57 Figura 28.. Visão geral da metodologia de síntese de alto nível ível do SynMaker SynMaker. 4.2.7. GERADOR RTL Depois de todas as análises análises feitas no arquivo de entrada, entrada, o SynMaker vai gerar código SystemVerilog códigos Verilog para serem incorporados no projeto base. As análises realizadas no passo anterior iram se transformar num objeto chamado enti entidade, dade, cada entidade representará um mód módulo ulo a ser sintetizado pelo SynMaker SynMaker,, essa entidade pode ser uma entidade HLSSystem que será utilizada para sintetizar o modulo TopLevel e uma entidade HLSNoHLSSystem que será utilizada para sintetizar os demais módulos do projeto. Essas entidades terão todas informações necessárias para gerar um RTL, informações como pinos de entrada, pinos de saída,, ligações, id do módulo, nome do módulo, dulo, módulos que estão instanciados, bloco combinacional e funções existentes. A partir dessa lista de entidade entidadess o SynMaker SynMaker fará a geração do d RTL. Para classes descritas na linguagem de alto nível que não serão sintetizadas no módulo dulo TopLevel do projeto base, ou seja classes que estendem HLSSynth, irá ser feito os seguintes passo: printModuleClass – Responsável por incluir o nome module. printModuleSynthName – Responsável por criar o nome do m módulo dulo a ser sintetizado. printModuleParameters – Os inputs, outputs do módulo dulo e seus respectivos nomes e tamanhos ssão ão sintetizados nesta nesta função função. printDeclarationInBody – Serão declarados aqui as variáveis que pertencem a módulos externos a este. PrintVariables – É criado criado o registrador de retorno do mó módulo dulo que será preenchido com o valor do bloco combinacional. PrintFunctions – A função que será chamada dentro do bloco combinac combinacional, always_comb, será gerada neste momento, com suas entradas, retorno e processamento interno. 58 PrintComb – O bloco combinacional será gerado neste momento e conterá a chamada para a função de execução do mó módulo dulo e seu retorno será colocado num registrador que é declar registrador declarado ado dentro do módulo. PrintFF – O bloco sequencial, always_ff, colocará a cada pulso de clock (posedge) o resultado contido no registrador que conterá o resultado do bloco combinacional num sinal de output, este sinal de output output será ligad ligadoo a uma saída do módulo. dulo. PrintLink – Neste momento são geradas todas as ligações do mó módulo, dulo, incluídas nelas a ligação entre a saída saída do always_ff ao output do módulo, e as ligações de entrada e saída do módulo módulo com as entradas e saídas de instancias de módulos que estão dentro deste módulo mó que esta sendo sintetizado. sintetizado. Nesta etapa também é gerada aas declarações dos fios (wire) que são necessários para realizar as ligações. PrintInstances – Aqui será gerada as iinstancias nstancias que estão dentro do mó módulo que está sendo sintetizado. printModuleClassEnd – Responsável apenas por incluir o final do mó módulo gerado, end module. 4.2.8. PLATAFORMA FPGA O resultado final do passo anterior será um arquivo SystemVerilog que pode ser sintetizado pela ferramenta Quartus II, o RTL é sintetizada em uma implementação FPGA utilizando a ferramenta comercial Quartus II que compila para placa DE2 DE2-70 com FPGA Cyclone II na plataforma de desenvolvimento de Câmera Digital da Alter Altera, o SynMaker usa um script TCL para criar um projeto Quartus e executar os seguintes comandos abaixo, conforme seqüencia ilustrada na Figura 29. Quartus_sh: Criar projeto e configurar o Quartus. Quartus_map: síntese de arquivos de concepção do projeto (por exemplo, o RTL ou netlist EDA), e elementos de design, mapas aos recursos do dispositivo. Quartus_fit: lugares e rotas dos recursos do dispositivo para o FPGA. Quartus_sta: realiza uma análise de tempo estático no design. Quartus_asm: Gera arquivo de programação .pof e .sof. Quartus_pgm: Executar o .pof. Antes da execução desses comandos o SynMaker realiza uma verificação para garantir que o Quartus II está instalado. Essa comunicação realiz realizada ada entre o Quartus II e o SynMaker é feita através do módulo GenerateProject. O arquivo TCL também é gerado automaticamente antes de ser executado, pois o projeto Quartus vai ter um módulo TopLevel diferente dependendo do código de entrada dado, que pode ter qualquer classe estendendo HLSSYSTEM. No fim, quando termina a execução de todas essas linhas de comando da Figura 29,, o resultado é um RTL transformado numa implementação FPGA completa sob a forma de um fluxo de bits programado nnaa plataforma FPGA alvo. Figura 29.. Seqüência de comandos executados pelo Quartus. 59 4.3 ARQUITETURA DO SYNMAKER O SynMaker foi desenvolvido seguindo a arquitetura Figura 30. As Unidades foram produzidas com capacidade de comunicarem entre si. A ferramenta SynMaker é composta por várias unidades, dentre elas são destacadas na sua arquitetura: A unidade de pré-compilação (PreCompiler Platform) que é a primeira unidade chamada tanto no processo de simulação quanto no processo de síntese e é responsável pela geração da árvore genérica a partir de códigos que vem através do usuário que é produzido para ser sintetizado e que será processado pelo Create AST File ou pela Create AST Lib que gerará a AST que representa os módulos do projeto base. Tudo isso será transformado numa AST genérica do SynMaker como produto final da précompilação, esta unidade ainda faz uso de uma outra unidade chamada Generic Abstract Syntax Tree que está dentro da unidade de pré-compilação, esta unidade será chamada para realizar o processo de geração da AST para diferentes linguagens, utilizando para cada uma dessas um parser específico e que por fim, essas diferentes árvores sintáticas serão unificadas em uma única árvore genérica que é o resultado final da unidade de pré-compilação. A unidade de simulação (Simulation – Platform) representa onde ocorrerá o processo de simulação da ferramenta SynMaker, esta unidade é subdividida em outros componentes que são Generate Simulation SynMaker and HLS System Class essa unidade é responsáveis pela geração da classes principais de simulação que serão compilada e executadas nas unidades posteriores. A classe gerada nessa unidade chamada de Simulation SynMaker class contém o método Main de execução da simulação e dentro dela serão criadas algumas linhas de códigos, inclusão de package de simulação e de instância da classe system e chamada do método run() desta classe que serão usadas de acordo com o que será simulado, é nessa classe também que há a interligação com a unidade HLS Simulation pertencente a unidade SynMaker Lib, pois será utilizada as classes dessa Lib que representará a simulação das classes que representam o projeto base, essas classes são responsáveis pela entrada e exibição de pixel. Três outras unidades são executadas logo depois, uma responsável pela compilação (Compile Simulation SynMaker Class) que irá executar o comando: javac -d bin -classpath lib\\jai_codec.jar;lib\\slf4j-simple-1.7.2.jar;lib\\slf4j-api1.7.2.jar;lib\\xuggle-xuggler-5.4.jar;lib\\jai_core.jar;lib\\jai_windowsi586.jar;lib\\simulationlib.jar *.java, para compilar as classes geradas pelas unidades anteriores, e uma unidade (Execute Simulation Igniter Class) responsável pela execução da classe SimulationSynMakerClass.java pelo comando: java -Xmx256m -cp bin;lib\\jai_codec.jar;lib\\slf4j-simple-1.7.2.jar;lib\\slf4japi-1.7.2.jar;lib\\xuggle-xuggler-5.4.jar;lib\\jai_core.jar;lib\\jai_windowsi586.jar;lib\\simulationlib.jar "+ fileSimulationClass +" "+ filesimu+ " " + projectSimulationPath+ " "+ separator+" "+ simulationtype, onde fileSimulationClass é a classe SimulationSynMakerClass.java, filesimu é o vídeo ou imagem que será dado como exemplo para simulação, projectSimulationPath é o caminho onde esta os arquivos de simulação, simulationtype é a indicação do tipo de simulação se será de vídeo ou imagem, e por fim a unidade Show Execute Results que é responsável por exibir os resultados interligando-se com a unidade Java API para teste de vídeo e imagem, que no caso para vídeo foi utilizada a Xuggler e para imagem a JAI para a geração do produto final. Synthesis – Plataform é a unidade de síntese propriamente dita, ela realizará todas as análises no código e verificações se restrições imposta pelo SynMaker estão 60 sendo cumpridas. Essa unidade possui dois componentes principais que é a unidade de Synthesis - Simple e a unidade de Synthesis - Optimization. A primeira é responsável por realizar uma síntese mais simples sem máquina de estado ou otimizações de potência ou desempenho através de alguma técnica específica, a primeira unidade da síntese simples realiza análises e verificações na AST genérica recebida pela unidade de pré-compilação, logo após a um mapeamento de ordem de sintetização de módulos, a unidade seguinte é a responsável por gerar o arquivo sintetizado que será usado na próxima etapa e por fim a unidade Quartus Ignition que se interliga com a plataforma Quartus II para geração do projeto Quartus, realização de síntese e análises nos seus projetos para FPGA, o SynMaker chama o QUARTUS II através da execução de linha de comando pelo shell no Linux ou pelo prompt de comando no Windows. A segunda é a unidade de síntese com otimização que esta dividido em unidade de DFG onde será gerado, nessa unidade, a representação intermediária para otimização, utilizando a árvore genérica vinda da unidade de pré-compilação, através do componente DFG Builder o SynMaker irá construir essa nova representação e poderá gerar um gráfico e utilizá-lo nos componentes que vem logo depois. A unidade SchedulingToRTL que fará a otimização seguirá os seguintes passos, análise do DFG para que seja otimizado na unidade Analyser, síntese do arquivo que representará a máquina de estado, transferência de dados e o arquivo principal de síntese otimizada o main. Uma observação é que o SchedulingToRTL ainda não conta, para essa versão do SynMaker, com um componente QuartusIgnition que irá realizar a função de criação do projeto e execução do mesmo na placa de prototipação. Figura 30. Arquitetura SynMaker. 61 5 EXPERIMENTOS E TESTES DE VALIDAÇÃO Nesta seção, será apresentada os experimentos e testes realizados utilizando o SynMaker. A ferramenta de síntese proposta foi implementada em Java e foram realizados alguns teste e experimentos de síntese utilizando código Java e SystemVerilog com sucesso. Esses testes e experimentos são explicados nas subseções deste capítulo. Os resultados mostram que SynMaker tem uma nova metodologia que foi testada e funciona bem, com algumas restrições, devido a implementações que ainda não foram feitas até o presente momento, as restrições foram mencionados nas seções anteriores. 5.1 AMBIENTE Os experimentos e testes foram realizados no sistema operacional Windows e Linux usando um computador com processador Intel core 2 duo 2.0 GHz com 2GB de memória DDR3. A 5.1.1 descreve os requisitos mínimos necessários para o funcionamento e como deve ser instalada a ferramenta. As outras subseções demonstram o ambiente de protipação utilizado pelo SynMaker para exibir o resultado da síntese, a plataforma de desenvolvimento de câmera digital Altera DE2-70. 5.1.1. REQUISITOS E INSTALAÇÃO A ferramenta de síntese SynMaker foi desenvolvida para funcionar no sistema operacional Windows ou Linux, qualquer outro sistema operacional que não seja nenhum desses dois, ao tentar executar a ferramenta, esta levantará uma exceção informando a incompatibilidade do sistema. O SynMaker se comunica com o Software Quartus II Web Edition, de preferência a versão 9.1. O Quartus II é necessário, caso o usuário da ferramenta queira, após a síntese, criar um projeto, compilar e programar automaticamente na placa de prototipação DE2-70 da Altera. É necessário o Java Development Kit (JDK 7) para a ferramenta realizar simulação de vídeo, pois o SynMaker faz compilação de .class Java para realizar essa ação. Para utilizar o SynMaker é necessário executá-lo através de seu .Jar ou fazer o download do projeto em http://carloslcj10.wix.com/synmaker e importá-lo logo depois para o Eclipse ou NetBeans e executa-lo através da classe Main. Outra opção é o usuário fazer o download do projeto através do SVN e importá-lo para o Eclipse ou NetBeans. Para que algumas funções funcionem corretamente é necessário setar algumas variáveis de ambiente. Como: - Java_Home :C:\Program Files\Java\jdk1.6.0_32 - QUARTUS_ROOTDIR :c:\altera\91\quartus - PATH: %QUARTUS_ROOTDIR%\bin;%JAVA_HOME%\bin; 62 5.1.2. TERASIC DE2-70 Para a prototipagem dos circuitos a partir da síntese de alto nível é necessário a utilização de uma placa de prototipação. O principal ambiente de prototipação rápida para desenvolvimento dos circuitos criados nesta dissertação de mestrado é a placa Terasic DE2-70 [5]. A placa possui diversos componentes, apresentados a seguir: USB Blaster (on board) for programming and user API control; both JTAG and Active Serial (AS) programming modes are supported. 2-Mbyte SSRAM Two 32-Mbyte SDRAM 8-Mbyte Flash memory SD Card socket 4 push button switches 18 toggle switches 18 red user LEDs 9 green user LEDs 50-Mhz oscillator and 28.63-Mhz oscillator for clock sources 24-bit CD-quality audio CODEC with line-in, line-out, and microphone-in jacks VGA DAC (10-bit high-speed triple DACs) with VGA-out connector 2 TV Decoder (NTSC/PAL) and TV-in connector 10/100 Ethernet Controllerwith a connector USB Host/Slave Controller with USB type A and type B connectors RS-232 transceiverand 9-pin connector PS/2 mouse/keyboard connector IrDA transceiver 1 SMA connector Two 40-pin Expansion Headers with diode protection O principal componente da placa é um FPGA Altera Cyclone® II 2C70, com cerca de 68k elementos lógicos programáveis. A placa possui 64MB de memória SDRAM, 2MB de memória SSRAM, 8MB de memória flash, dois decodificadores de TV e diversos dispositivos para suporte de entrada e saída de dados, de áudio e de vídeo. Entre estes há um canal de rede ethernet, uma porta serial PS/2, uma saída de vídeo analógica VGA além de diversos pinos de GPIO. A Figura 31, apresenta uma visão geral da placa. 63 Figura 31. Placa de desenvolvimento Altera D2-70. A arquitetura principal da placa Terasic DE2-70 é apresentada na Figura 32. Neste caso, os principais componentes são citados, bem como as portas de comunicação e configuração, as linhas de clock e demais dispositivos. Figura 32. Estrutura de componentes e comunicação da placa D2-70. 64 Além dos componentes presentes na placa principal, há dois conectores para viabilizar a integração de placas de expansão. Há várias placas de expansão disponíveis, para os mais diversos fins e que são extremamente úteis no projeto e desenvolvimento de aplicações. Em particular, há duas placas que se destacam quando o foco do projeto é voltado para a área de visão computacional. São as placas TRDB-D5M e TRDB-LTH. A placa TRDB-D5M possui uma câmera digital com um sensor CMOS Micron com resolução máxima de 5 megapixels. Esta câmera é capaz de atuar tanto na captura de imagens estáticas como para vídeo. Assim, se configura como um importante meio de entrada para qualquer aplicação que trabalhe com captura de imagens para processamento, como as aplicações de visão computacional. Figura 33, ilustra está placa. Figura 33. Placa TRDB-D5M. A placa TRDB-LTH possui um display de 4.3 polegadas LCD colorido, com resolução de 800 por 480 pontos. O display é sensível a toque e possui alta resolução. Assim, é um relevante dispositivo de saída para qualquer aplicação que tenha a necessidade de exibir imagens, sejam estas simplesmente capturadas ou ainda processadas por algum algoritmo de tratamento de imagens. No caso particular de aplicações de visão computacional, este display é de fundamental importância por permitir a exibição imediata dos resultados provenientes dos algoritmos de análise e processamento dos dados de entrada. O display pode assim exibir em tempo real o produto do que foi processado pelos algoritmos sintetizados em hardware pela ferramenta de síntese de alto nível desenvolvida neste trabalho, viabilizando várias aplicações que exigem captura processamento, inferência de informação a partir de imagens e, finalmente, sua exibição. A Figura 34 ilustra esta placa de expansão. Figura 34. Placa TRDB-LTH. 65 5.1.3. O FPGA EP2C70: CIRCUITO LÓGICO RECONFIGURÁVEL O FPGA presente na placa de desenvolvimento é um Altera Cyclone® II tipo EP2C70. Mais precisamente, um FPGA EP2C70F896C6, que é o maior e mais complexo componente presente na família Cyclone II. A Figura 35 ilustra o dispositivo em questão. Figura 35. Dispositivo FPGA EP2C70F896C6. Este componente possui 68416 unidades lógicas programáveis, 250 blocos de memória RAM interna M4K com paridade, 1152k bits de memória RAM interna total, 150 multiplicadores aritméticos (18 por 18) e quatro multiplicadores de clock (PLL's). O dispositivo permite ainda que cada multiplicador aritmético de 18x18 seja configurado como dois de 9x9 bits. Estão disponíveis um máximo de 622 pinos de entrada e saída (I/O) de propósito geral para o projetista, dos quais 16 podem atuar como sinais dedicados de clock, para cada uma das 16 redes internas globais de clock. O componente possui um encapsulamento BGA (ball grid array), composto por uma matriz de esferas na superfície inferior para integração com a placa-mãe. A Figura 36, apresenta a estrutura interna de um FPGA EP2C70F896C6, ilustrando a disposição dos PLL's, dos multiplicadores dedicados, dos blocos de IO, dos blocos lógicos programáveis e ainda dos blocos internos de memória M4K. Por questões de simplicidade, a extensa malha de interconexão interna de sinais foi suprimida. 66 Figura 36. Estrutura interna do FPGA EP2C70F896C6. Os blocos de memória interna M4K podem ser configurados de diversas maneiras, de modo a fornecerem grande flexibilidade ao projeto. Em particular é possível acessar cada um como uma unidade única de 4k ou como duas unidades de 2k, entre outras das várias configurações disponíveis. 5.2 EXECUÇÃO Inicialmente foram realizados testes unitários para validação da síntese da ferramenta, esses testes consistiram em realização da síntese em pequenos trechos de códigos para verificar se o parser estava gerando corretamente a árvore, se está árvore gerada estava sendo corretamente transformada na árvore genérica proposta e se a síntese utilizando esta representação intermediária estava acontecendo corretamente, a Tabela 5 mostra alguns desses testes unitários. Os testes foram classificados pela linguagem de entrada Java ou SystemVerilog e com ou sem otimização. Para esta versão a maioria dos testes foram realizados usando a linguagem Java como entrada e sínteses de alto nível sem otimização, mas alguns testes foram realizados para confirmar que a ferramenta também é capaz de gerar RTL com outras linguagens como SystemVerilog e usar a síntese de alto nível com otimização. Na Tabela 5 mostra um conjunto de testes que foram realizados pela ferramenta, primeiro, foram realizados experimentos o número 1, 2, 3, 4 e 5 que são testes básicos para consolidar metodologia utilizada pela ferramenta. Depois de validar a síntese por unidade, foram feitos experimentos de aplicações de processamento de imagem (síntese de código e execução do mesmo na placa de prototipação) para demonstrar que o SynMaker é capaz de realizar sínteses de alto nível e executar em uma plataforma FPGA. A Figura 37.a mostra o funcionamento do projeto básico da plataforma de desenvolvimento de câmera digital Altera DE2-70. A Figura 37.b mostrar o mesmo projeto, mas agora com módulos gerados e colocados automaticamente pelo SynMaker, o processo inicia-se com um código em Java de um 67 filtro de processamento de imagem chamado filtro de Sobel e finaliza-se com este filtro em execução na placa. Outros filtros de processamento de imagem também foram testados e alguns aplicativos simples de manipulação de imagem também ratificaram o funcionamento ferramenta. Nº Teste Linguage m de entrada Tipo de Metodologia 1 Síntese de Declaration, Assignment, Binary Expressions, Unary Expressions, Literal Expressions, Name Expressions JAVA/ SYSTEM VERILOG SIMPLES/ OTIMIZADA 2 Síntese de Array and Method Call Expression JAVA SIMPLES 3 Sínteseof Object Creation Expression JAVA/ SYSTEM VERILOG SIMPLES 4 Síntese de For and If Statements JAVA SIMPLE 5 Síntese de function, Constructions and Classes JAVA/ SYSTEM VERILOG SIMPLES / OTIMIZADA Tabela 5. Testes de validação realizados. Alguns experimentos foram executados para confirmar o funcionamento da metodologia e da ferramenta SynMaker. Para executar os experimentos inicialmente é escolhido um filtro de processamento de imagem, este filtro é codificado em linguagem de alto nível, a linguagem usada nesses experimentos foi o Java, após desenvolvimento do algoritmo, este filtro é testado utilizando a própria ferramenta SynMaker, através do seu simulador com o comando sm_simu. Após a verificação de que este código funciona em alto nível, o mesmo é dado como entrada para o SynMaker realizar a síntese, cria-se primeiro o projeto pelo comando sm_create, copia-se o código que foi desenvolvido para o projeto criado e depois pelo comando sm_synth “caminho do código desenvolvido” –scp realiza-se a síntese. Este comando de síntese irá gerar além do código sintetizado, um projeto para plataforma Quartus II que conterá todos os módulos do projeto base de execução da câmera e o código sintetizado embutida nele, esse projeto é executado logo após a sua criação na placa de prototipação DE2-70 com câmera digital da altera. Esse procedimento foi realizado com alguns filtros clássicos de processamento de imagem, dentre eles estão, Filtro de Sobel com três tipos de implementação diferente, Filtro de Mediana, Filtro de Média, Filtro de Binarização, Conversão para escala de cinza e mudança de cores na tela. Para confirmar o funcionamento da metodologia explicada na seção 4.2.6 o exemplo do filtro do sobel foi implementado de três maneiras diferentes em alto nível e gerou o mesmo resultado. 68 (a) (b) Figura 37. Altera DE2-70 Digital Camera Development Platform. (a) Projeto Base. (b) Projeto base alterado pelo SynMaker com o filtro de sobel. 5.3 ANÁLISE E INTERPRETAÇÃO Os experimentos de aplicações de processamento de imagem foram realizados, analisados e apresentaram os resultados resumidos na Tabela 6, esses dados foram adquiridos usando a ferramenta Quartus II Web Edition 9.1. Os resultados para cada um desses experimentos é relativo ao projeto completo gerado pela ferramenta, não apenas para o módulo sintetizado para algoritmo do filtro de processamento de imagem que é dado como entrada, ou seja, além dos módulos sintetizados pela ferramenta a um o conjunto de módulos básicos que complementam o projeto neste resultado apresentado. Projeto Base com Algoritmo de processamento de imagem Filtro de Sobel implementação 1 Filtro de Sobel implementação 2 Filtro de Sobel implementação 3 Filtro de Média Filtro de Binarização Conversão escala de cinza Total de registradores Total de elementos lógicos Período de Clock (ns) Total de potência estática (mW) 1499 2725 7.223 565.42 1539 2728 6.556 574.46 1530 2729 6.324 570.55 1495 1489 1329 2925 2970 2084 7.015 6.178 6.726 581.65 592.81 540.06 Tabela 6. Resultado da síntese do SynMaker para filtros de processamento de imagem. Os resultados demonstrados na Tabela 6 consistem nos filtros e aplicações de processamento de imagens testados no SynMaker, tanto o código em alto nível quanto o código sintetizado do filtro de sobel implementação 1 presente na primeira coluna podem ser vistos nos anexos. O total de registradores e elementos lógicos foi conseguido através do sumário da análise de compilação do Quartus II, o total de energia foi obtido pela ferrramenta Power Analyzer Tool e o período de clock pela ferramenta Classic Timing Analyzer, ambas presente também no software Quartus II. O Filtro de Sobel foi sintetizado de três maneiras diferentes, a primeira maneira o código em Java possui apenas uma classe e uma função para o algoritmo do filtro completo, a segunda maneira o código do filtro possui três classes, sendo uma delas 69 com uma função com parte do código do filtro, outra classe com uma função que determinar o limiar do filtro e a terceira classe com outra função que realiza troca de sinal do pixel. A terceira maneira o filtro possui duas classes, sendo uma delas com duas funções internas, onde uma destas funções contém parte do código do filtro, e a outra função determina o limiar do filtro e outra classe contém apenas uma função que faz a mudança de sinal do pixel, dentre elas a primeira maneira de implementação obteve um consumo de energia, um total de registradores e uma quantidade de elementos lógicos inferior as outras, porém um período de clock maior. O total de elementos lógicos foi muito próximo entre as três implementações e a implementação número três foi a que obteve o menor período de clock. Dentre todas as aplicações sintetizadas a que apresentou menor consumo de energia, menor número de registradores e elementos lógicos foi a conversão para escala de cinza e menor período de clock foi o Filtro de binarização. Dentre eles o filtro que apresentou maior ciclo de clock foi o filtro de média, o que apresentou maior consumo e maior numero de elementos lógicos foi o filtro de binarização, entre tanto quem apresentou maior quantidade de registradores na síntese foi a segunda maneira de implementação do filtro de sobel. 70 6 CONSIDERAÇÕES FINAIS 6.1 CONTRIBUIÇÕES Foi apresentada, nesta dissertação, uma nova ferramenta para síntese de alto nível de filtros de processamento de imagem desenvolvidos em Java ou SystemVerilog, também foi demonstrado, através de vários exemplos, que a metodologia utilizada na ferramenta é bastante eficiente, convertendo vários algoritmos de filtros de processamento de imagem desenvolvido em linguagem de alto nível orientada a objeto, com restrições, em seu RTL correspondente. Com isso é possível concluir que este trabalho contribuiu com a comunidade científica por ter sido desenvolvido um novo sistema de síntese de alto nível, com um fluxo de projeto e metodologia de síntese para plataformas FPGA que o designer de circuitos pode programar em qualquer linguagem, se essa linguagem é suportada pela ferramenta, este programa é convertido em uma representação intermediária Genérica da ferramenta que gerará uma implementação RTL que pode ser compilada e programada para a plataforma FPGA DE2-70 de Câmera Digital da Altera através do Software Quartus II. Incluídos na ferramenta ainda estão presentes um parser SystemVerilog, um parser JAVA, uma representação intermediária Genérica e uma metodologia de síntese própria para desenvolver projetos que funcionaram na plataforma de desenvolvimento de câmera digital da altera. 6.2 TRABALHOS FUTUROS Os Trabalhos futuro poderão se concentrar em implementar um middleware para suportar o compilador LLVM. O código objecto Optimized do LLVM pode ser convertido para a representação intermédia genérica do SynMaker e depois o SynMaker continua o seu fluxo de síntese. Permitir a síntese de algoritmos de processamento de imagem mais sofisticados, algoritmos de inteligência artificial e realidade aumentada. A ferramenta precisa ser expandida para mais dispositivos que estão presentes no Altera DE2-70 Digital Platform Development Camera - Terasic, esses dispositivos por exemplo, são o display de sete segmentos, leds, botões de comutação, conexão de rede Ethernet, de comunicação sem fio e outros, os seus dispositivos precisam ser adicionados na biblioteca de síntese de alto Nível, como foi feito com os módulos LTM e TOUCH_TCON, que devido a isso podem ser usados na síntese da ferramenta. Outro trabalho que pode ser feito é expandir a ferramenta para dar apoio para mais linguagens e outras sintaxes que ainda não estão implementadas ou não estão definidas na metodologia. A esperança é que SynMaker facilite a concepção, desenvolvimento e interação entre o designer e projetos de hardware. 71 REFERÊNCIAS ADAMS, J. K.; THOMAS, D.E. Tutorial: The Design of Mixed Hardware/Software Systems. DAC, 1996, p. 515–520. [2] ADVE, V.; LATTNER, C. LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation, Symposium on Code Generation and Optimization (CGO 2004), IEEE CS Press, p. 75–86. [3] ADIMEC. Disponível em:<http://info.adimec.com/blogposts/bid/39656/CCD-vsCMOS-Image-Sensors-in-Machine-Vision-Cameras>.Acesso em: 04/03/2013. [4] ADOLFO, G.; ALVAREZ, P. Especificação e Implementação de uma Representação Intermediária Unificada para Sistemas Digitais. Master’s Dissertation, Polytechnic School of University of São Paulo, São Paulo, Brazil, 2005. 135 pages. [5] ALTERA CORPORATION. 1995-2012. Disponível em: <http://www.altera.com>. Acesso em: 17/04/2013. [6] AMELLAL, S.; KAMINSK, B. Scheduling of a control and data flow graph. IEEE Int. Symposium on Circuits and Systems, 3:1666–1669, May 1993. [7] AUERBACH, J. et al. Lime: a Java-compatible and synthesizable language for heterogeneous architectures. SIGPLAN Conferences, Not. 45, 10 (October 2010), 89-108. [8] AUTOESL DESIGN TECHNOLOGIES, INC. AutoESL's AutoPilot. 2010. Disponível em: <http://www.autoesl.com/autopilto_fpga.htm>. Acesso em: 01 out. 2011. [9] BERGAMASCHI, R. A. Bridging the domains of high-level and logic synthesis. Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions, v. 21, n. 5, p. 582-596, mai 2002, doi: 10.1109/43.998629. Disponível em <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=998629&isnumber=215 47>. Acesso em: 21 nov. 2011. [10] BERKELEY DESIGN TECHNOLOGY, INC. An Independent Evaluation of: High-Level Synthesis Tools for Xilinx FPGAs, 2010. Disponível em: <www.BDTI.com>.Acesso em: 1 mar. 2012. [11] CALYPTO DESIGN SYSTEMS, INC. Catapult C Synthesis. 2010. Disponível em:<http://www.mentor.com/products/esl/high_level_synthesis/catapult_synthesis>. Acesso em: 01 out. 2011. [12] CANIS, A. et al. LegUp: high-level synthesis for FPGA-based processor/accelerator systems. In Proceedings of the 19th ACM/SIGDA international symposium on Field programmable gate arrays (FPGA '11), 2011, New York, NY, USA, p. 3336, DOI=10.1145/1950413.1950423. Disponível em: <http://doi.acm.org/10.1145/1950413.1950423>. Acesso em: 10 jan. 2012. [13] CASSEAU, E.; LE GAL, B. High-level synthesis for the design of FPGA-based signal processing systems. Systems, Architectures, Modeling, and Simulation. SAMOS 2009 International Symposium, p.25-32, 20-23, jul. 2009, DOI: 10.1109/ICSAMOS.2009.5289238. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5289238&isnumbe r=5289219>. Acesso em: 12 fev. 2012. [14] CHEN, D et al. LOPASS: A Low-Power Architectural Synthesis System for FPGAs With Interconnect Estimation and Optimization.Very Large Scale Integration (VLSI) Systems, IEEE Transactions, v. 18, n. 4, p. 564-577, abr 2010 doi: [1] 72 10.1109/TVLSI.2009.2013353. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5109476&isnumber=54 37466>. Acesso em: 21 nov. 2011. [15] CROMAR, S.; LEE, J.; CHEN, D. FPGA-targeted high-level binding algorithm for power and area reduction with glitch-estimation. In Proceedings of the 46th Annual Design Automation Conference (DAC 2009). ACM, New York, NY, USA, 838-843, DOI=10.1145/1629911.1630125. Disponível em <http://doi.acm.org/10.1145/1629911.1630125>. Acesso em: 12 nov. 2011. [16] CONG, J. et al. High-Level Synthesis for FPGAs: From Prototyping to Deployment. Computer-Aided Design of Integrated Circuits and Systems, IEEE Transactions, v.30, n.4, p.473-491, abr. 2011, doi:10.1109/TCAD.2011.2110592. Disponível em <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5737854&isnumber=5 737840>. Acesso em: 20 mar. 2012. [17] COUSSY, P. GAUT: High-Level Synthesis tool From C to RTL. 2010. Disponível em: <http://www-labsticc.univ-ubs.fr/www-gaut/>. Acesso em: 15 out. 2011. [18] COUSSY, P. et al. An Introduction to High-Level Synthesis.Design & Test of Computers, IEEE, v. 26, n. 4, p. 8-17, ago. 2009, doi: 10.1109/MDT.2009.69. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5209958&isnumber=52 09950>. Acesso em: 14 out. 2011. [19] COUSSY, P.; LHAIRECH-LEBRETON, G.; MARTIN, E. Hierarchical and Multiple-Clock Domain High-Level Synthesis for Low-Power Design on FPGA. Field Programmable Logic and Applications (FPL), 2010 International Conference, p. 464-468, ago. 31 2010, doi: 10.1109/FPL.2010.94. Disponível em <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5694295&isnumber=56 94025>. Acesso em: 03 abr. 2012. [20] EDWARDS, S et al. Design of Embedded Systems: Formal Model, Validation and Synthesi. Proceedings of the IEEE 85(3), 366–390, 1997. [21] EJNIOUI, A; NAMBALLA, R.; RANGANATHAN, N. Control and data flow graph extraction for high-level synthesis. Proceedings. IEEE Computer society Annual Symposium. VLSI, 2004. p.187-192, 19-20 fev. 2004, doi:10.1109/ISVLSI.2004.1339528. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1339528&isnumber=29 536>. Acesso em: 22 out. 2011. [22] GAJSKI, D. et al. Specification and Design of EmbeddedSystems, Prentice-Hall, Englewood Cliffs, N. J., 1994. [23] GILL, A. Introduction to the Theory of Finite-State Machines. Electronic Sciences Series, McGraw-Hill, New York, NY 10020, USA; 1962. [24] GONZALEZ, R. C.; WOODS, R. E. Digital Image Processing. 2ª ed. New Jersey: Prentice Hall, 2002. [25] GUPTA, R. K.; DE MICHELI, G. System Synthesis via Hardware-Software CoDesign, Technical Report CSL-TR-1992-548, Stanford University, Computer Systems Laboratory. [26] GUPTA, S. et al. SPARK: A parallelizing approach to the High-Level synthesis of digital circuits. Kluwer Academic Publishers, 2004. [27] IMPULSE C ACCELERATED TECHNOLOGIES. Disponível em: <http://www.impulseaccelerated.com/>. Acesso em: 20/03/2013. 73 KASTENBERG, H.; KLEPPE, A.G.; RENSINK, A. Engineering Object-Oriented Semantics Using Graph Transformations. Technical Report TR-CTIT-2006-12, Centre for Telematics and Information Technology University of Twente, Enschede. ISSN 1381-3625. [29] LEP MOTION. Disponível em: <https://leapmotion.com/>.Acesso em: 12/03/2013. [30] MARTIN, G.; SMITH, G. High-Level Synthesis: Past, Present, and Future. IEEE Design and Test of Computers, Jul. 2009. [31] MARTIN, S. A. M. F. Ferramenta de apoio ao desenvolvimento de sistemas de processamento de imagem em tempo real implementados em plataformas reconfiguráveis. Departamento de Engenharia Eletronica e de Computadores, Porto, 2007. [32] OBRIZAN, V. A method for automatic generation of an RTL-interface from a C++ description. Design & Test Symposium (EWDTS), 2010, East-West, p.186-189, 17-20, set.2010, doi:10.1109/EWDTS.2010.5742152. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5742152&isnumbe r=5742029>. Acesso em: 23 jan. 2012. [33] PHILIPPE, C.; MORAWIEC, A. High-level Synthesis: From Algorithm To Digital Circuit. Springer, 2008. [34] RANGANATHAN, N.; NAMBALLA, R.; HANCHATE, N. CHESS: a comprehensive tool for CDFG extraction and synthesis of low power designs from VHDL. Emerging VLSI Technologies and Architectures, IEEE Computer Society Annual Symposium, v.0, p.6, p.2-3, mar. 2006, DOI: 10.1109/ISVLSI.2006.27.Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1602460&isnumbe r=33676>. Acesso em: 12 nov. 2011. [35] SINHA, S.; SRIKANTHAN, T. Hardware complexity metrics for high level synthesis of software functions. VLSI Design, Automation and Test (VLSI-DAT), 2011 International Symposium, p. 1-4, 25-28 abr. 2011, doi:10.1109/VDAT.2011.5783553. Disponível em: <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=5783553&isnumber=57 83538>. Acesso em: 02 mar. 2012. [36] SUTHERLAND, S. et al. SystemVerilog for Design Second Edition: A Guide to Using SystemVerilog for Hardware Design and Modeling. Out. 29, 2010, Springer. [37] SYSTEMC USER´S GUIDE VERSION 2.0. Disponível em: <http://www.cse.iitd.ac.in/~panda/SYSTEMC/LangDocs/UserGuide20.pdf> Acessado em: 04/04/2013. [38] TERASIC ALTERA. Disponível em:<http://www.terasic.com.tw/cgibin/page/archive.pl?No=226>.Acesso em: 18/03/2013. [39] The Source for Java(TM) Technology Collaboration. Java Compiler Compiler (JavaCC). Disponível em:<http://javacc.dev.java.net/>. Acesso em: 13 set. 2011. [40] TRIPP, J.L.; GOKHALE, M.B.; PETERSON, K.D. Trident: From High-Level Language to Hardware Circuitry. IEEE Computer, v.40, n.3, p.28-37, mar.2007, DOI:10.1109/MC.2007.107. Disponível em: < http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4133993&isnumber=4 133979>. Acesso em: 10 fev. 2012. [41] VALLERIO, K. S.; JHA, N. K. Task graph extraction for embedded system synthesis. Proceedings 16th International Conference, VLSI Design, 2003. p. 480- 486, 4-8 Jan. 2003, doi: 10.1109/ICVD.2003.1183180. Disponível em: [28] 74 <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1183180&isnumber=26 547>. Acesso em: 17 out. 2011. [42] VAREA, M. Modelling And Verification Of Embedded Systems Based On Petri Net Oriented Representations. Tese (Doutorado) - Department Of Electronics And Computer Science, University Of Southampton, United Kingdom, 2003. 75 7 ANEXO Anexo I Código do Filtro de Sobel desenvolvido em Java Este código escrito em linguagem Java é um exemplo de entrada aceito pelo SynMaker, o mesmo pode ser sintetizado e simulado pela ferramenta. O código está presente em um só arquivo chamado de TestSobel.java e possui duas classes que serão sintetizadas pela ferramenta, onde a primeira classe chamada Sobel possui uma função chamada fsobel que realiza a alteração nos pixels da imagem de acordo com o algoritmo de Sobel e outra chamada de sinal_cor que apenas inverte a magnitude de escala de cinza. A outra classe TestSobel que representa a classe top-level do sistema, esta classe possui, apenas, o método run que representa a natureza cíclica do funcionamento da aplicação, em outras palavras tudo que estiver dentro desse método deve ser pensado pelo usuário como se estivesse num laço infinito, é também onde deve ser implementada as chamadas de funções iniciais da aplicação. // Federal University of Pernambuco - UFPE // Center for Information Technology - CIN //2013/07/22 17:01:50 package br.ufpe.cin.hls.sample; import import import import br.ufpe.cin.hlslib.system.HLSSynth; br.ufpe.cin.hlslib.system.HLSSystem; br.ufpe.cin.hlslib.system.LTM; br.ufpe.cin.hlslib.system.touch_tcon; class Sobel extends HLSSynth { final int vetor=1056; int oy; int[] buffer=new int[2*vetor+3]; public { int fsobel(int a,int b, int c) int soma; int somay,somax; int y; int x; int[][] GX = new int[3][3]; int[][] GY = new int[3][3]; 76 int res; // Máscara GX[0][0] = GX[1][0] = GX[2][0] = de Sobel -1; GX[0][1] = 0; GX[0][2] = 1; -2; GX[1][1] = 0; GX[1][2] = 2; -1; GX[2][1] = 0; GX[2][2] = 1; GY[0][0] = 1; GY[0][1] = 2; GY[0][2] = 1; GY[1][0] = 0; GY[1][1] = 0; GY[1][2] = 0; GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1; oy= (a+b+c)/3; // gera tons de cinza // Carregar e deslocar o buffer (tamanho do buffer : 2 linhas e 3 pixels) for(int m=0;m<vetor*2+2;m++) buffer[m]=buffer[m+1]; buffer[vetor*2+2]= oy; //Reinicialização de variáveis somax=0; somay=0; x= 1; y= 1; // Realizar convoluções // GRADIENTE X for(int i= -1; i<=1; i=i+1) { for(int j=-1; j<=1; j=j+1) { somax = somax + buffer[x+i+(y + j)*vetor]*GX[i+1][j+1]; } } // GRADIENTE Y for(int i=-1; i<=1;i=i+1) { for(int j=-1;j<=1;j=j+1) { somay = somay + buffer[x+i+(y + j)*vetor]*GY[i+1][j+1]; } } // MAGNITUDE DOS GRADIENTE if (somax<0) somax=-somax; if (somay<0) somay=-somay; res=somax+somay; // Definição do limiar para o filtro if(res>255) res=0; else if(res<0) res=0; else if(res>=0 && res<=25) res=0; else res=255; return res; } 77 public { int sinal_cor(int d) // inversão da escala de cinza int res; res= 255-d; return res; } } public class TestSobel extends HLSSystem{ // Instanciação de objetos que representam IPs do Projeto base LTM ltm=new LTM(); touch_tcon tcon=new touch_tcon(); // Instanciação de objeto que será sintetizado pela ferramenta e posteriormente // inserido no Projeto base Sobel sobel2=new Sobel(); // Método obrigatório presente na classe que será sintetizada no modulo top-level do projeto public void run() { int iLCD_R_t=0, iLCD_G_t=0,iLCD_B_t=0; int oLCD_t ; int pixel_sobel_t; iLCD_R_t = iLCD_G_t = iLCD_B_t = tcon.getNextPixelR(); //output_1 tcon.getNextPixelG(); //output_2 tcon.getNextPixelB(); //output_3 pixel_sobel_t=sobel2.fsobel(iLCD_R_t,iLCD_G_t,iLCD_B_t);//input_1,2,3 ; output_4 oLCD_t=sobel2.sinal_cor(pixel_sobel_t);//input_4 ; output_5 ltm.setLtm_r(oLCD_t);//input_5 ltm.setLtm_b(oLCD_t);//input_6 ltm.setLtm_g(oLCD_t);//input_7 } } 78 Anexo II Código SystemVerilog Gerado pelo SynMaker a partir do código de exemplo do Anexo I, relativo a Classe Sobel. Esse código é sintetizado pelo SynMaker a partir do código de entrada dado pelo anexo I, mas especificamente pela parte do código relativa a classe Sobel, o mesmo pode fazer parte de um projeto da ferramenta Quartus II e posteriormente pode ser compilado e programado na placa DE2-70, esse projeto pode ser eventualmente o projeto base descrito nessa dissertação. // File Generated by SynMaker High Level Synthesis Tools // Federal University of Pernambuco - UFPE // Center for Information Technology - CIN //2013/07/22 17:01:50 module Sobel( input logic SobelfsobeliCLK , input logic SobelfsobeliRST_n , input int Sobelfsobel_input_3 , input int Sobelfsobel_input_4 , input int Sobelfsobel_input_5 , input logic Sobelsinal_coriCLK , input logic Sobelsinal_coriRST_n , input int Sobelsinal_cor_input_3 , output int Sobelfsobel_output_1 , output int Sobelsinal_cor_output_1 ); assign SobelfsobeliCLK_sign = SobelfsobeliCLK; assign SobelfsobeliRST_n_sign = SobelfsobeliRST_n; assign Sobelfsobel_input_3_sign = Sobelfsobel_input_3; assign Sobelfsobel_input_4_sign = Sobelfsobel_input_4; assign Sobelfsobel_input_5_sign = Sobelfsobel_input_5; assign Sobelfsobel_output_1 = Sobelfsobel_output_1_sign; assign Sobelsinal_coriCLK_sign = Sobelsinal_coriCLK; assign Sobelsinal_coriRST_n_sign = Sobelsinal_coriRST_n; assign Sobelsinal_cor_input_3_sign = Sobelsinal_cor_input_3; assign Sobelsinal_cor_output_1 = Sobelsinal_cor_output_1_sign; Sobelfsobel Sobelfsobel( .Sobelfsobel_output_1(Sobelfsobel_output_1_sign), .SobelfsobeliCLK(SobelfsobeliCLK_sign), .SobelfsobeliRST_n(SobelfsobeliRST_n_sign), .Sobelfsobel_input_3(Sobelfsobel_input_3_sign), .Sobelfsobel_input_4(Sobelfsobel_input_4_sign), .Sobelfsobel_input_5(Sobelfsobel_input_5_sign) ); wire [31:0] Sobelfsobel_output_1_sign; wire [31:0] SobelfsobeliCLK_sign; wire [31:0] SobelfsobeliRST_n_sign; wire [31:0] Sobelfsobel_input_3_sign; wire [31:0] Sobelfsobel_input_4_sign; wire [31:0] Sobelfsobel_input_5_sign; Sobelsinal_cor Sobelsinal_cor( .Sobelsinal_cor_output_1(Sobelsinal_cor_output_1_sign), .Sobelsinal_coriCLK(Sobelsinal_coriCLK_sign), 79 .Sobelsinal_coriRST_n(Sobelsinal_coriRST_n_sign), .Sobelsinal_cor_input_3(Sobelsinal_cor_input_3_sign) ); wire [31:0] Sobelsinal_cor_output_1_sign; wire [31:0] Sobelsinal_coriCLK_sign; wire [31:0] Sobelsinal_coriRST_n_sign; wire [31:0] Sobelsinal_cor_input_3_sign; endmodule 80 Anexo III Código SystemVerilog Gerado pelo SynMaker a partir do código de exemplo do Anexo I, relativo a Função Run da Classe TestSobel. Esse código é sintetizado pelo SynMaker a partir do código de entrada dado pelo anexo I, mas especificamente pela parte do código relativa a Função Run da classe TestSobel, o mesmo pode fazer parte de um projeto da ferramenta Quartus II e posteriormente pode ser compilado e programado na placa DE2-70, esse projeto pode ser eventualmente o projeto base descrito nessa dissertação. // File Generated by SynMaker High Level Synthesis Tools // Federal University of Pernambuco - UFPE // Center for Information Technology - CIN //2013/07/22 17:01:50 module TestSobelrun( input logic TestSobelruniCLK , input logic TestSobelruniRST_n , input int TestSobelrunltm_b , input int TestSobelrunltm_r , input int TestSobelrunltm_g , input int TestSobelrunoLCD_G , input int TestSobelrunoLCD_R , input int TestSobelrunoLCD_B , input int TestSobelrunSobelfsobel_output_1 , input int TestSobelrunSobelsinal_cor_output_1 , output int TestSobelrunltm_b_input , output int TestSobelrunltm_r_input , output int TestSobelrunltm_g_input , output int TestSobelrunSobelfsobel_input_3 , output int TestSobelrunSobelfsobel_input_4 , output int TestSobelrunSobelfsobel_input_5 , output int TestSobelrunSobelsinal_cor_input_3 ); function void run ( ); int iLCD_R_t = 0, iLCD_G_t = 0, iLCD_B_t = 0; int oLCD_t; int pixel_sobel_t; endfunction assign iLCD_R_t_sign = TestSobelrunoLCD_R; assign iLCD_G_t_sign = TestSobelrunoLCD_G; assign iLCD_B_t_sign = TestSobelrunoLCD_B; assign TestSobelrunSobelfsobel_input_3 = iLCD_R_t_sign; assign TestSobelrunSobelfsobel_input_4 = iLCD_G_t_sign; assign TestSobelrunSobelfsobel_input_5 = iLCD_B_t_sign; assign pixel_sobel_t_sign = TestSobelrunSobelfsobel_output_1; assign TestSobelrunSobelsinal_cor_input_3 = pixel_sobel_t_sign; assign oLCD_t_sign = TestSobelrunSobelsinal_cor_output_1; assign TestSobelrunltm_r_input = oLCD_t_sign; assign TestSobelrunltm_b_input = oLCD_t_sign; assign TestSobelrunltm_g_input = oLCD_t_sign; wire [31:0] iLCD_R_t_sign; wire [31:0] iLCD_G_t_sign; wire [31:0] iLCD_B_t_sign; wire [31:0] pixel_sobel_t_sign; wire [31:0] oLCD_t_sign; endmodule 81 Anexo IV Código SystemVerilog Gerado pelo SynMaker a partir do código de exemplo do Anexo I, relativo a Função Sinal_cor da Classe Sobel. Esse código é sintetizado pelo SynMaker a partir do código de entrada dado pelo anexo I, mas especificamente pela parte do código relativa a Função Sinal_cor da classe Sobel, o mesmo pode fazer parte de um projeto da ferramenta Quartus II e posteriormente pode ser compilado e programado na placa DE2-70, esse projeto pode ser eventualmente o projeto base descrito nessa dissertação. module Sobelsinal_cor( input logic Sobelsinal_coriCLK , input logic Sobelsinal_coriRST_n , input int Sobelsinal_cor_input_3 , output int Sobelsinal_cor_output_1 ); parameter int vetor = 1056; int oy; int buffer[2 * vetor + 3:0]; int return_Sobelsinal_cor_output_1 ; function int sinal_cor ( input int d ); int res; res = 255 - d; return res; endfunction always_comb begin return_Sobelsinal_cor_output_1 = sinal_cor(Sobelsinal_cor_input_3); end always_ff @(posedge Sobelsinal_coriCLK ) begin Sobelsinal_cor_output_1_sign <= return_Sobelsinal_cor_output_1; end assign Sobelsinal_cor_output_1 = Sobelsinal_cor_output_1_sign; wire [31:0] Sobelsinal_cor_output_1_sign; endmodule 82 Anexo V Código SystemVerilog Gerado pelo SynMaker a partir do código de exemplo do Anexo I, relativo a Função fsobel da Classe Sobel. Esse código é sintetizado pelo SynMaker a partir do código de entrada dado pelo anexo I, mas especificamente pela parte do código relativa a função fsobel da classe Sobel, o mesmo pode fazer parte de um projeto da ferramenta Quartus II e posteriormente pode ser compilado e programado na placa DE2-70, esse projeto pode ser eventualmente o projeto base descrito nessa dissertação. // File Generated by High Level Synthesis Tools // Federal University of Pernambuco - UFPE // Center for Information Technology - CIN //2013/07/22 17:01:50 module Sobelfsobel( input logic SobelfsobeliCLK , input logic SobelfsobeliRST_n , input int Sobelfsobel_input_3 , input int Sobelfsobel_input_4 , input int Sobelfsobel_input_5 , output int Sobelfsobel_output_1 ); parameter int vetor = 1056; int oy; int buffer[2 * vetor + 3:0]; int return_Sobelfsobel_output_1 ; function int fsobel ( input int a, input int b, input int c ); int soma; int somay, somax; int y; int x; int GX[3:0][3:0]; int GY[3:0][3:0]; int res; GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1; GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2; GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1; GY[0][0] = 1; GY[0][1] = 2; GY[0][2] = 1; GY[1][0] = 0; GY[1][1] = 0; GY[1][2] = 0; GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1; oy = (a + b + c) / 3; somax = 0; somay = 0; x = 1; y = 1; for (int i = -1; i <= 1; i = i + 1) begin 83 for (int j = -1; j <= 1; j = j + 1) begin somax = somax + buffer[x + i + (y + j) * vetor] * GX[i + 1][j + 1]; end end for (int i = -1; i <= 1; i = i + 1) begin for (int j = -1; j <= 1; j = j + 1) begin somay = somay + buffer[x + i + (y + j) * vetor] * GY[i + 1][j + 1]; end end if (somax < 0) begin somax = -somax; end if (somay < 0) begin somay = -somay; end res = somax + somay; if (res > 255) begin res = 0; end else if (res < 0) begin res = 0; end else if (res >= 0 && res <= 25) begin res = 0; end else begin res = 255; end return res; endfunction always_comb begin return_Sobelfsobel_output_1 = fsobel(Sobelfsobel_input_3,Sobelfsobel_input_4,Sobelfsobel_input_5); end always_ff @(posedge SobelfsobeliCLK ) begin Sobelfsobel_output_1_sign <= return_Sobelfsobel_output_1; for (int m = 0; m < vetor * 2 + 2; m++) begin buffer[m] <= buffer[m + 1]; end 84 buffer[vetor * 2 + 2] <= oy; end assign Sobelfsobel_output_1 = Sobelfsobel_output_1_sign; wire [31:0] Sobelfsobel_output_1_sign; endmodule 85 Anexo VI Código SystemVerilog do módulo LTM, pertencente ao projeto base. Esse código não é sintetizado pelo SynMaker, ele faz parte do projeto base onde vão ser inseridos os RTLs gerados pela ferramenta. module LTM ltm_b_input, ( input wire [7:0] ltm_r_input, input wire [7:0] ltm_g_input, input wire [7:0] input wire ltm_hd_input, input wire ltm_vd_input, input wire ltm_den_input, output wire [7:0] ltm_r, output wire [7:0] ltm_g, output wire [7:0] ltm_b,output wire ltm_hd, output wire ltm_vd, output wire ltm_den ); assign ltm_r = ltm_r_input; assign ltm_g = ltm_g_input; assign ltm_b = ltm_b_input; assign ltm_hd = ltm_hd_input; assign ltm_vd = ltm_vd_input; assign ltm_den = ltm_den_input; endmodule 86 Anexo VII Código SystemVerilog do módulo touch_tcon, pertencente ao projeto base. Esse código não é sintetizado pelo SynMaker, ele faz parte do projeto base onde vão ser inseridos os RTLs gerados pela ferramenta. // -------------------------------------------------------------------// Copyright (c) 2007 by Terasic Technologies Inc. // -------------------------------------------------------------------// // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------// // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: [email protected] // // -------------------------------------------------------------------// // Major Functions: DE2 LTM module Timing control and output image data // form sdram // // -------------------------------------------------------------------// // Revision History : // -------------------------------------------------------------------// Ver :| Author :| Mod. Date :| Changes Made: // V1.0 :| Johnny Fan :| 07/06/30 :| Initial Revision // -------------------------------------------------------------------module touch_tcon iCLK, iRST_n, // SDRAM SIDE iREAD_DATA1, iREAD_DATA2, oREAD_SDRAM_EN, ( // LCD display clock // systen reset // R and G color data form sdram // B color data form sdram // read sdram data control signal 87 //LCD SIDE oHD, // LCD Horizontal sync oVD, // LCD Vertical sync oDEN, // LCD Data Enable oLCD_R, // LCD Red color data oLCD_G, // LCD Green color data oLCD_B, // LCD Blue color data ); //============================================================================ // PARAMETER declarations //============================================================================ parameter H_LINE = 1056; parameter V_LINE = 525; parameter Hsync_Blank = 216; parameter Hsync_Front_Porch = 40; parameter Vertical_Back_Porch = 35; parameter Vertical_Front_Porch = 10; //=========================================================================== // PORT declarations //=========================================================================== input iCLK; input iRST_n; input [15:0] iREAD_DATA1; input [15:0] iREAD_DATA2; output oREAD_SDRAM_EN; output [7:0] oLCD_R; output [7:0] oLCD_G; output [7:0] oLCD_B; output oHD; output oVD; output oDEN; //============================================================================= // REG/WIRE declarations //============================================================================= reg [10:0] x_cnt; reg [9:0] y_cnt; wire [7:0] read_red; wire [7:0] read_green; wire [7:0] read_blue; wire display_area; wire oREAD_SDRAM_EN; reg mhd; reg mvd; reg mden; reg oHD; reg oVD; reg oDEN; reg [7:0] oLCD_R; reg [7:0] oLCD_G; reg [7:0] oLCD_B; //============================================================================= // Structural coding //============================================================================= // This signal control reading data form SDRAM , if high read color data form sdram . assign oREAD_SDRAM_EN = ( (x_cnt>Hsync_Blank-2)&& (x_cnt<(H_LINE-Hsync_Front_Porch-1))&& (y_cnt>(Vertical_Back_Porch-1))&& (y_cnt<(V_LINE - Vertical_Front_Porch)) )? 1'b1 : 1'b0; // This signal indicate the lcd display area . assign display_area = ((x_cnt>(Hsync_Blank-1)&& //>215 (x_cnt<(H_LINE-Hsync_Front_Porch))&& //< 1016 (y_cnt>(Vertical_Back_Porch-1))&& (y_cnt<(V_LINE - Vertical_Front_Porch)) )) ? 1'b1 : 1'b0; 88 assign assign assign read_red = display_area ? iREAD_DATA2[9:2] : 8'b0; read_green = display_area ? {iREAD_DATA1[14:10],iREAD_DATA2[14:12]}: 8'b0; read_blue = display_area ? iREAD_DATA1[9:2] : 8'b0; ///////////////////////// x y counter and lcd hd generator ////////////////// always@(posedge iCLK or negedge iRST_n) begin if (!iRST_n) begin x_cnt <= 11'd0; mhd <= 1'd0; end else if (x_cnt == (H_LINE-1)) begin x_cnt <= 11'd0; mhd <= 1'd0; end else begin x_cnt <= x_cnt + 11'd1; mhd <= 1'd1; end end always@(posedge iCLK or negedge iRST_n) begin if (!iRST_n) y_cnt <= 10'd0; else if (x_cnt == (H_LINE-1)) begin if (y_cnt == (V_LINE-1)) y_cnt <= 10'd0; else y_cnt <= y_cnt + 10'd1; end end ////////////////////////////// touch panel timing ////////////////// always@(posedge iCLK or negedge iRST_n) begin if (!iRST_n) mvd <= 1'b1; else if (y_cnt == 10'd0) mvd <= 1'b0; else mvd <= 1'b1; end always@(posedge iCLK or negedge iRST_n) begin if (!iRST_n) mden <= 1'b0; else if (display_area) mden <= 1'b1; else mden <= 1'b0; end always@(posedge iCLK or negedge iRST_n) begin if (!iRST_n) begin oHD <= 1'd0; oVD <= 1'd0; oDEN <= 1'd0; oLCD_R <= 8'd0; 89 oLCD_G <= 8'd0; oLCD_B <= 8'd0; end else begin oHD <= mhd; oVD <= mvd; oDEN <= mden; oLCD_R <= read_red; oLCD_G <= read_green; oLCD_B <= read_blue; end end endmodule 90 Anexo VIII Código SystemVerilog do módulo TestSobel. Esse código representa o módulo top-level gerado pelo SynMaker, a ferramenta altera o módulo top-level do projeto base para gerar esse código, de acordo com o que foi programado na classe TestSobel que foi dada de entrada, mostrada no Anexo I. // File Generated by High Level Synthesis Tools // Federal University of Pernambuco - UFPE // Center for Information Technology - CIN // 2013/07/22 17:01:50 // Based In File: // // -------------------------------------------------------------------// Copyright (c) 2008 by Terasic Technologies Inc. // -------------------------------------------------------------------// // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------// // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: [email protected] // // -------------------------------------------------------------------// // Major Functions: DE2_70 D5M LTM // // -------------------------------------------------------------------// // Revision History : // -------------------------------------------------------------------// Ver :| Author :| Mod. Date :| Changes Made: // V1.0 :| Keith Shen :| 08/04/16 :| Initial Revision // -------------------------------------------------------------------module TestSobel ( 91 //////////////////// iCLK_28, iCLK_50, iCLK_50_2, iCLK_50_3, iCLK_50_4, iEXT_CLOCK, //////////////////// iKEY, //////////////////// iSW, //////////////////// oHEX0_D, 0 oHEX0_DP, decimal point oHEX1_D, 1 oHEX1_DP, decimal point oHEX2_D, 2 oHEX2_DP, decimal point oHEX3_D, 3 oHEX3_DP, decimal point oHEX4_D, 4 oHEX4_DP, decimal point oHEX5_D, 5 oHEX5_DP, decimal point oHEX6_D, 6 oHEX6_DP, decimal point oHEX7_D, 7 oHEX7_DP, decimal point //////////////////////// oLEDG, oLEDR, //////////////////////// oUART_TXD, iUART_RXD, oUART_CTS, iUART_RTS, //////////////////////// oIRDA_TXD, iIRDA_RXD, ///////////////////// DRAM_DQ, 32 Bits oDRAM0_A, bus 13 Bits oDRAM1_A, bus 13 Bits oDRAM0_LDQM0, oDRAM1_LDQM0, oDRAM0_UDQM1, Mask oDRAM1_UDQM1, Clock Input Push Button DPDT Switch 7-SEG Dispaly //////////////////// // 28.63636 MHz // 50 MHz // // // // //////////////////// // //////////////////// // //////////////////// // 50 MHz 50 MHz 50 MHz External Clock Pushbutton[3:0] Toggle Switch[17:0] Seven Segment Digit // Seven Segment Digit 0 // Seven Segment Digit // Seven Segment Digit 1 // Seven Segment Digit // Seven Segment Digit 2 // Seven Segment Digit // Seven Segment Digit 3 // Seven Segment Digit // Seven Segment Digit 4 // Seven Segment Digit // Seven Segment Digit 5 // Seven Segment Digit // Seven Segment Digit 6 // Seven Segment Digit // Seven Segment Digit 7 LED UART IRDA //////////////////////// // // LED Green[8:0] LED Red[17:0] // // UART Transmitter UART Receiver //////////////////////// // // //////////////////////// SDRAM Interface UART Clear To Send UART Requst To Send // // IRDA Transmitter IRDA Receiver // SDRAM Data bus // SDRAM0 Address // SDRAM1 Address //////////////// // // // SDRAM0 Low-byte Data Mask SDRAM1 Low-byte Data Mask SDRAM0 High-byte Data // SDRAM1 High-byte Data 92 Mask oDRAM0_WE_N, // SDRAM0 Write Enable oDRAM1_WE_N, // SDRAM1 Write Enable oDRAM0_CAS_N, // SDRAM0 Column Address Strobe oDRAM1_CAS_N, // SDRAM1 Column Address Strobe oDRAM0_RAS_N, // SDRAM0 Row Address Strobe oDRAM1_RAS_N, // SDRAM1 Row Address Strobe oDRAM0_CS_N, // SDRAM0 Chip Select oDRAM1_CS_N, // SDRAM1 Chip Select oDRAM0_BA, // SDRAM0 Bank Address oDRAM1_BA, // SDRAM1 Bank Address oDRAM0_CLK, // SDRAM0 Clock oDRAM1_CLK, // SDRAM1 Clock oDRAM0_CKE, // SDRAM0 Clock Enable oDRAM1_CKE, // SDRAM1 Clock Enable //////////////////// Flash Interface //////////////// FLASH_DQ, // FLASH Data bus 15 Bits (0 to 14) FLASH_DQ15_AM1, // FLASH Data bus Bit 15 or Address A-1 oFLASH_A, // FLASH Address bus 26 Bits oFLASH_WE_N, // FLASH Write Enable oFLASH_RST_N, // FLASH Reset oFLASH_WP_N, // FLASH Write Protect /Programming Acceleration iFLASH_RY_N, // FLASH Ready/Busy output oFLASH_BYTE_N, // FLASH Byte/Word Mode Configuration oFLASH_OE_N, // FLASH Output Enable oFLASH_CE_N, // FLASH Chip Enable //////////////////// SRAM Interface //////////////// SRAM_DQ, // SRAM Data Bus 32 Bits SRAM_DPA, // SRAM Parity Data Bus oSRAM_A, // SRAM Address bus 22 Bits oSRAM_ADSC_N, // SRAM Controller Address Status oSRAM_ADSP_N, // SRAM Processor Address Status oSRAM_ADV_N, // SRAM Burst Address Advance oSRAM_BE_N, // SRAM Byte Write Enable oSRAM_CE1_N, // SRAM Chip Enable oSRAM_CE2, // SRAM Chip Enable oSRAM_CE3_N, // SRAM Chip Enable oSRAM_CLK, // SRAM Clock oSRAM_GW_N, // SRAM Global Write Enable oSRAM_OE_N, // SRAM Output Enable oSRAM_WE_N, // SRAM Write Enable //////////////////// ISP1362 Interface //////////////// OTG_D, // ISP1362 Data bus 16 Bits oOTG_A, // ISP1362 Address 2 Bits oOTG_CS_N, // ISP1362 Chip Select oOTG_OE_N, // ISP1362 Read oOTG_WE_N, // ISP1362 Write oOTG_RESET_N, // ISP1362 Reset OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable 93 iOTG_INT0, iOTG_INT1, iOTG_DREQ0, Request 0 iOTG_DREQ1, Request 1 oOTG_DACK0_N, // oOTG_DACK1_N, // //////////////////// LCD Module 16X2 //////////////// oLCD_ON, ON/OFF oLCD_BLON, ON/OFF oLCD_RW, Select, 0 = Write, 1 = Read oLCD_EN, oLCD_RS, Command/Data Select, 0 = Command, 1 = Data LCD_D, // //////////////////// SD_Card Interface //////////////// SD_DAT, SD_DAT3, SD_CMD, Signal oSD_CLK, //////////////////// I2C //////////////////////////// I2C_SDAT, oI2C_SCLK, //////////////////// PS2 //////////////////////////// PS2_KBDAT, PS2_KBCLK, PS2_MSDAT, PS2_MSCLK, //////////////////// VGA //////////////////////////// oVGA_CLOCK, // oVGA_HS, oVGA_VS, oVGA_BLANK_N, // oVGA_SYNC_N, // oVGA_R, oVGA_G, oVGA_B, //////////// Ethernet Interface //////////////////////// ENET_D, // oENET_CMD, Command/Data Select, 0 = Command, 1 = Data oENET_CS_N, Select oENET_IOW_N, // oENET_IOR_N, // oENET_RESET_N, // iENET_INT, oENET_CLK, MHz //////////////// Audio CODEC //////////////////////// AUD_ADCLRCK, // iAUD_ADCDAT, // AUD_DACLRCK, // oAUD_DACDAT, // AUD_BCLK, Stream Clock oAUD_XCK, Clock //////////////// TV Decoder //////////////////////// iTD1_CLK27, Line_Lock Output Clock iTD1_D, // // // // ISP1362 Interrupt 0 ISP1362 Interrupt 1 ISP1362 DMA // ISP1362 DMA ISP1362 DMA Acknowledge 0 ISP1362 DMA Acknowledge 1 // LCD Power // LCD Back Light // LCD Read/Write // // LCD Enable LCD LCD Data bus 8 bits // // // SD Card Data SD Card Data 3 SD Card Command // SD Card Clock // // I2C Data I2C Clock // // // // PS2 Keyboard Data PS2 Keyboard Clock PS2 Mouse Data PS2 Mouse Clock VGA Clock // VGA H_SYNC // VGA V_SYNC VGA BLANK VGA SYNC // VGA Red[9:0] // VGA Green[9:0] // VGA Blue[9:0] DM9000A DATA bus 16Bits // DM9000A // DM9000A Chip DM9000A Write DM9000A Read DM9000A Reset // DM9000A Interrupt // DM9000A Clock 25 Audio CODEC ADC LR Clock Audio CODEC ADC Data Audio CODEC DAC LR Clock Audio CODEC DAC Data // Audio CODEC Bit// Audio CODEC Chip // TV Decoder1 TV Decoder1 Data bus 8 bits 94 iTD1_HS, iTD1_VS, oTD1_RESET_N, iTD2_CLK27, Line_Lock Output Clock iTD2_D, iTD2_HS, iTD2_VS, oTD2_RESET_N, //////////////////// GPIO GPIO_0, I/O GPIO_CLKIN_N0, 0 GPIO_CLKIN_P0, GPIO_CLKOUT_N0, GPIO_CLKOUT_P0, GPIO_1, I/O GPIO_CLKIN_N1, GPIO_CLKIN_P1, GPIO_CLKOUT_N1, GPIO_CLKOUT_P1 // // // TV Decoder1 H_SYNC TV Decoder1 V_SYNC TV Decoder1 Reset // TV Decoder2 // // // // TV Decoder2 Data bus 8 bits TV Decoder2 H_SYNC TV Decoder2 V_SYNC TV Decoder2 Reset //////////////////////////// // // GPIO Connection 0 GPIO Connection 0 Clock Input // // GPIO Connection 0 Clock Input 1 // GPIO Connection 0 Clock Output 0 GPIO Connection 0 Clock Output 1 // GPIO Connection 1 // GPIO Connection 1 Clock Input 0 // GPIO Connection 1 Clock Input 1 // GPIO Connection 1 Clock Output 0 // GPIO Connection 1 Clock Output 1 ); //=========================================================================== // PARAMETER declarations //=========================================================================== //=========================================================================== // PORT declarations //=========================================================================== //////////////////////// Clock Input //////////////////////// input iCLK_28; // 28.63636 MHz input iCLK_50; // 50 MHz input iCLK_50_2; // 50 MHz input iCLK_50_3; // 50 MHz input iCLK_50_4; // 50 MHz input iEXT_CLOCK; // External Clock //////////////////////// Push Button //////////////////////// input [3:0] iKEY; // Pushbutton[3:0] //////////////////////// DPDT Switch //////////////////////// input [17:0] iSW; // Toggle Switch[17:0] //////////////////////// 7-SEG Dispaly //////////////////////// output [6:0] oHEX0_D; // Seven Segment Digit 0 output oHEX0_DP; // Seven Segment Digit 0 decimal point output [6:0] oHEX1_D; // Seven Segment Digit 1 output oHEX1_DP; // Seven Segment Digit 1 decimal point output [6:0] oHEX2_D; // Seven Segment Digit 2 output oHEX2_DP; // Seven Segment Digit 2 decimal point output [6:0] oHEX3_D; // Seven Segment Digit 3 output oHEX3_DP; // Seven Segment Digit 3 decimal point output [6:0] oHEX4_D; // Seven Segment Digit 4 output oHEX4_DP; // Seven Segment Digit 4 decimal point output [6:0] oHEX5_D; // Seven Segment Digit 95 5 output Digit 5 decimal point output [6:0] 6 output Digit 6 decimal point output [6:0] 7 output Digit 7 decimal point //////////////////////////// output [8:0] output [17:0] //////////////////////////// output Transmitter input Receiver output input //////////////////////////// output Transmitter input Receiver /////////////////////// inout [31:0] 32 Bits output [12:0] bus 13 Bits output [12:0] bus 13 Bits output Data Mask output Data Mask output Data Mask output Data Mask output Enable output Enable output Address Strobe output Address Strobe output Address Strobe output Address Strobe output Select output Select output [1:0] Address output [1:0] Address output Clock output Clock output Clock Enable oHEX5_DP; // Seven Segment oHEX6_D; // oHEX6_DP; // Seven Segment oHEX7_D; // oHEX7_DP; // // iUART_RXD; IRDA // // LED Green[8:0] LED Red[17:0] // UART // UART UART Clear To Send UART Requst To Send iIRDA_RXD; SDRAM Interface DRAM_DQ; Seven Segment Digit // Seven Segment LED //////////////////////////// oLEDG; oLEDR; UART //////////////////////////// oUART_TXD; oUART_CTS; iUART_RTS; //////////////////////////// oIRDA_TXD; Seven Segment Digit // IRDA // IRDA //////////////////////// // SDRAM Data bus oDRAM0_A; // SDRAM0 Address oDRAM1_A; // SDRAM1 Address oDRAM0_LDQM0; // SDRAM0 Low-byte oDRAM1_LDQM0; // SDRAM1 Low-byte oDRAM0_UDQM1; // SDRAM0 High-byte oDRAM1_UDQM1; // SDRAM1 High-byte oDRAM0_WE_N; // SDRAM0 Write oDRAM1_WE_N; // SDRAM1 Write oDRAM0_CAS_N; // SDRAM0 Column oDRAM1_CAS_N; // SDRAM1 Column oDRAM0_RAS_N; // SDRAM0 Row oDRAM1_RAS_N; // SDRAM1 Row oDRAM0_CS_N; // SDRAM0 Chip oDRAM1_CS_N; // SDRAM1 Chip oDRAM0_BA; // SDRAM0 Bank oDRAM1_BA; // SDRAM1 Bank oDRAM0_CLK; // SDRAM0 oDRAM1_CLK; // SDRAM1 oDRAM0_CKE; // SDRAM0 96 output oDRAM1_CKE; // SDRAM1 Clock Enable //////////////////////// Flash Interface //////////////////////// inout [14:0] FLASH_DQ; // FLASH Data bus 15 Bits (0 to 14) inout FLASH_DQ15_AM1; // FLASH Data bus Bit 15 or Address A-1 output [21:0] oFLASH_A; // FLASH Address bus 26 Bits output oFLASH_WE_N; // FLASH Write Enable output oFLASH_RST_N; // FLASH Reset output oFLASH_WP_N; // FLASH Write Protect /Programming Acceleration input iFLASH_RY_N; // FLASH Ready/Busy output output oFLASH_BYTE_N; // FLASH Byte/Word Mode Configuration output oFLASH_OE_N; // FLASH Output Enable output oFLASH_CE_N; // FLASH Chip Enable //////////////////////// SRAM Interface //////////////////////// inout [31:0] SRAM_DQ; // SRAM Data Bus 32 Bits inout [3:0] SRAM_DPA; // SRAM Parity Data Bus output [18:0] oSRAM_A; // SRAM Address bus 21 Bits output oSRAM_ADSC_N; // SRAM Controller Address Status output oSRAM_ADSP_N; // SRAM Processor Address Status output oSRAM_ADV_N; // SRAM Burst Address Advance output [3:0] oSRAM_BE_N; // SRAM Byte Write Enable output oSRAM_CE1_N; // SRAM Chip Enable output oSRAM_CE2; // SRAM Chip Enable output oSRAM_CE3_N; // SRAM Chip Enable output oSRAM_CLK; // SRAM Clock output oSRAM_GW_N; // SRAM Global Write Enable output oSRAM_OE_N; // SRAM Output Enable output oSRAM_WE_N; // SRAM Write Enable //////////////////// ISP1362 Interface //////////////////////// inout [15:0] OTG_D; // ISP1362 Data bus 16 Bits output [1:0] oOTG_A; // ISP1362 Address 2 Bits output oOTG_CS_N; // ISP1362 Chip Select output oOTG_OE_N; // ISP1362 Read output oOTG_WE_N; // ISP1362 Write output oOTG_RESET_N; // ISP1362 Reset inout OTG_FSPEED; // USB Full Speed, 0 = Enable, Z = Disable inout OTG_LSPEED; // USB Low Speed, 0 = Enable, Z = Disable input iOTG_INT0; // ISP1362 Interrupt 0 input iOTG_INT1; // ISP1362 Interrupt 1 input iOTG_DREQ0; // ISP1362 DMA Request 0 input iOTG_DREQ1; // ISP1362 DMA Request 1 output oOTG_DACK0_N; // ISP1362 DMA Acknowledge 0 output oOTG_DACK1_N; // ISP1362 DMA Acknowledge 1 97 //////////////////// LCD Module 16X2 //////////////////////////// inout [7:0] LCD_D; output oLCD_ON; Power ON/OFF output oLCD_BLON; Back Light ON/OFF output oLCD_RW; Read/Write Select, 0 = Write, 1 = Read output oLCD_EN; Enable output oLCD_RS; Command/Data Select, 0 = Command, 1 = Data //////////////////// SD Card Interface //////////////////////// inout SD_DAT; Data inout SD_DAT3; Data 3 inout SD_CMD; Command Signal output oSD_CLK; Clock //////////////////////// I2C //////////////////////////////// inout I2C_SDAT; output oI2C_SCLK; Clock //////////////////////// PS2 //////////////////////////////// inout PS2_KBDAT; Keyboard Data inout PS2_KBCLK; Keyboard Clock inout PS2_MSDAT; Mouse Data inout PS2_MSCLK; Mouse Clock //////////////////////// VGA //////////////////////////// output oVGA_CLOCK; output oVGA_HS; H_SYNC output oVGA_VS; V_SYNC output oVGA_BLANK_N; output oVGA_SYNC_N; output [9:0] oVGA_R; output [9:0] oVGA_G; output [9:0] oVGA_B; //////////////// Ethernet Interface //////////////////////////// inout [15:0] ENET_D; bus 16Bits output oENET_CMD; DM9000A Command/Data Select, 0 = Command, 1 = Data output oENET_CS_N; DM9000A Chip Select output oENET_IOW_N; output oENET_IOR_N; output oENET_RESET_N; input iENET_INT; DM9000A Interrupt output oENET_CLK; DM9000A Clock 25 MHz //////////////////// Audio CODEC //////////////////////////// inout AUD_ADCLRCK; LR Clock input iAUD_ADCDAT; Data inout AUD_DACLRCK; LR Clock output oAUD_DACDAT; // // LCD Data bus 8 bits // LCD // LCD // LCD // LCD // LCD // SD Card // SD Card // SD Card // SD Card // // I2C Data I2C // PS2 // PS2 // PS2 // PS2 VGA Clock // VGA // VGA // // // // // VGA BLANK VGA SYNC VGA Red[9:0] VGA Green[9:0] VGA Blue[9:0] // DM9000A DATA // // // // // DM9000A Write DM9000A Read DM9000A Reset // // // Audio CODEC ADC // Audio CODEC ADC // Audio CODEC DAC // Audio CODEC DAC 98 Data inout AUD_BCLK; CODEC Bit-Stream Clock output oAUD_XCK; CODEC Chip Clock //////////////////// TV Devoder input iTD1_CLK27; Decoder1 Line_Lock Output Clock input [7:0] iTD1_D; bus 8 bits input iTD1_HS; H_SYNC input iTD1_VS; V_SYNC output oTD1_RESET_N; input iTD2_CLK27; Decoder2 Line_Lock Output Clock input [7:0] iTD2_D; bus 8 bits input iTD2_HS; H_SYNC input iTD2_VS; V_SYNC output oTD2_RESET_N; // Audio // Audio // TV //////////////////////////// // TV Decoder1 Data // TV Decoder1 // TV Decoder1 // TV Decoder1 Reset // TV // TV Decoder2 Data // TV Decoder2 // TV Decoder2 // TV Decoder2 Reset //////////////////////// GPIO //////////////////////////////// inout [31:0] GPIO_0; // GPIO Connection 0 I/O input GPIO_CLKIN_N0; // GPIO Connection 0 Clock Input 0 input GPIO_CLKIN_P0; // GPIO Connection 0 Clock Input 1 inout GPIO_CLKOUT_N0; // GPIO Connection 0 Clock Output 0 inout GPIO_CLKOUT_P0; // GPIO Connection 0 Clock Output 1 inout [31:0] GPIO_1; // GPIO Connection 1 I/O input GPIO_CLKIN_N1; // GPIO Connection 1 Clock Input 0 input GPIO_CLKIN_P1; // GPIO Connection 1 Clock Input 1 inout GPIO_CLKOUT_N1; // GPIO Connection 1 Clock Output 0 inout GPIO_CLKOUT_P1; // GPIO Connection 1 Clock Output 1 /////////////////////////////////////////////////////////////////// //============================================================================= // REG/WIRE declarations //============================================================================= // wire wire wire wire wire wire wire wire CCD [11:0] wire wire wire wire wire wire wire wire wire wire wire wire [15:0] [15:0] [11:0] [15:0] [15:0] [9:0] [31:0] CCD_DATA; CCD_SDAT; CCD_SCLK; CCD_FLASH; CCD_FVAL; CCD_LVAL; CCD_PIXCLK; CCD_MCLK; // CCD Master Clock Read_DATA1; Read_DATA2; VGA_CTRL_CLK; mCCD_DATA; mCCD_DVAL; mCCD_DVAL_d; X_Cont; Y_Cont; X_ADDR; Frame_Cont; DLY_RST_0; DLY_RST_1; 99 wire wire reg reg reg wire wire wire wire wire wire wire reg wire [11:0] [11:0] [11:0] [11:0] [9:0] [9:0] [9:0] DLY_RST_2; Read; rCCD_DATA; rCCD_LVAL; rCCD_FVAL; sCCD_R; sCCD_G; sCCD_B; sCCD_DVAL; oVGA_R; oVGA_G; oVGA_B; [1:0] rClk; sdram_ctrl_clk; // // // VGA Red[9:0] VGA Green[9:0] VGA Blue[9:0] wire [9:0] mVGA_R; wire [9:0] mVGA_G; wire [9:0] mVGA_B; wire [7:0] Yout; wire out_enable; wire [7:0] wire [7:0] wire [7:0] wire [7:0] sobel_out ; oLCDs_R; oLCDs_G; oLCDs_B; wire [7:0] DISP_R; wire [7:0] DISP_G; wire [7:0] DISP_B; wire den; wire [9:0] r; wire [9:0] g; wire [9:0] b; //============================================================================= // Structural coding //============================================================================= assign CCD_DATA[0] = GPIO_1[11]; assign CCD_DATA[1] = GPIO_1[10]; assign CCD_DATA[2] = GPIO_1[9]; assign CCD_DATA[3] = GPIO_1[8]; assign CCD_DATA[4] = GPIO_1[7]; assign CCD_DATA[5] = GPIO_1[6]; assign CCD_DATA[6] = GPIO_1[5]; assign CCD_DATA[7] = GPIO_1[4]; assign CCD_DATA[8] = GPIO_1[3]; assign CCD_DATA[9] = GPIO_1[2]; assign CCD_DATA[10]= GPIO_1[1]; assign CCD_DATA[11]= GPIO_1[0]; assign GPIO_CLKOUT_N1 = CCD_MCLK; assign CCD_FVAL = GPIO_1[18]; assign CCD_LVAL = GPIO_1[17]; assign CCD_PIXCLK = GPIO_CLKIN_N1; assign GPIO_1[15] = 1'b1; // tRIGGER assign GPIO_1[14] = DLY_RST_1; assign oLEDR = //assign oLEDR[0] = out_enable; iSW; assign Y_Cont; oLEDG = 100 assign assign oTD1_RESET_N = 1'b1; oVGA_CLOCK = always@(posedge iCLK_50) rClk ~VGA_CTRL_CLK; <= rClk+1; always@(posedge CCD_PIXCLK) begin rCCD_DATA <= CCD_DATA; rCCD_LVAL <= CCD_LVAL; rCCD_FVAL <= CCD_FVAL; end Reset_Delay .iRST(iKEY[0]), .oRST_0(DLY_RST_0), .oRST_1(DLY_RST_1), .oRST_2(DLY_RST_2) ); u1 ( .iCLK(iCLK_50), CCD_Capture .oDVAL(mCCD_DVAL), .oX_Cont(X_Cont), .oY_Cont(Y_Cont), .oFrame_Cont(Frame_Cont), .iDATA(rCCD_DATA), .iFVAL(rCCD_FVAL), .iLVAL(rCCD_LVAL), .iSTART(!iKEY[3]), .iEND(!iKEY[2]), .iCLK(CCD_PIXCLK), .iRST(DLY_RST_2) ); u2 ( .oDATA(mCCD_DATA), u3 ( .oSEG0(oHEX0_D),.oSEG1(oHEX1_D), RAW2RGB .iRST_n(DLY_RST_1), .iData(mCCD_DATA), .iDval(mCCD_DVAL), .oRed(sCCD_R), .oGreen(sCCD_G), .oBlue(sCCD_B), .oDval(sCCD_DVAL), .iMIRROR(iSW[17]), .iX_Cont(X_Cont), .iY_Cont(Y_Cont) ); SEG7_LUT_8 .oSEG2(oHEX2_D),.oSEG3(oHEX3_D), .oSEG4(oHEX4_D),.oSEG5(oHEX5_D), .oSEG6(oHEX6_D),.oSEG7(oHEX7_D), .iDIG(Frame_Cont[31:0]) ); u4 ( vga_pll .c0(ltm_nclk), .c1() ); u5 ( .inclk0(iCLK_50_2), sdram_pll .c0(sdram_ctrl_clk), .c1(oDRAM0_CLK), .c2(oDRAM1_CLK) ); u6 ( .inclk0(iCLK_50_3), .iCLK(CCD_PIXCLK), 101 assign CCD_MCLK = rClk[0]; Sdram_Control_4Port u7 .REF_CLK(iCLK_50), .RESET_N(1'b1), .CLK(sdram_ctrl_clk), ( // HOST Side // FIFO Write Side 1 .WR1_DATA({sCCD_G[11:7], sCCD_B[11:2]}), .WR1(sCCD_DVAL), .WR1_ADDR(0), .WR1_MAX_ADDR(800*480), .WR1_LENGTH(9'h100), .WR1_LOAD(!DLY_RST_0), .WR1_CLK(CCD_PIXCLK), // FIFO Read Side 1 .RD1_DATA(Read_DATA1), .RD1(Read), .RD1_ADDR(0), .RD1_MAX_ADDR(800*480), .RD1_LENGTH(9'h100), .RD1_LOAD(!DLY_RST_0), .RD1_CLK(~ltm_nclk), // SDRAM Side .SA(oDRAM0_A[11:0]), .BA(oDRAM0_BA), .CS_N(oDRAM0_CS_N), .CKE(oDRAM0_CKE), .RAS_N(oDRAM0_RAS_N), .CAS_N(oDRAM0_CAS_N), .WE_N(oDRAM0_WE_N), .DQ(DRAM_DQ[15:0]), .DQM({oDRAM0_UDQM1,oDRAM0_LDQM0}) ); Sdram_Control_4Port u8 .REF_CLK(iCLK_50), .RESET_N(1'b1), .CLK(sdram_ctrl_clk), ( // HOST Side // FIFO Write Side 1 .WR1_DATA({sCCD_G[6:2], sCCD_R[11:2]}), .WR1(sCCD_DVAL), .WR1_ADDR(0), .WR1_MAX_ADDR(800*480), .WR1_LENGTH(9'h100), .WR1_LOAD(!DLY_RST_0), .WR1_CLK(CCD_PIXCLK), // FIFO Read Side 1 .RD1_DATA(Read_DATA2), .RD1(Read), .RD1_ADDR(0), .RD1_MAX_ADDR(800*480), .RD1_LENGTH(9'h100), .RD1_LOAD(!DLY_RST_0), .RD1_CLK(~ltm_nclk), // SDRAM Side .SA(oDRAM1_A[11:0]), .BA(oDRAM1_BA), .CS_N(oDRAM1_CS_N), .CKE(oDRAM1_CKE), .RAS_N(oDRAM1_RAS_N), 102 .CAS_N(oDRAM1_CAS_N), .WE_N(oDRAM1_WE_N), .DQ(DRAM_DQ[31:16]), .DQM({oDRAM1_UDQM1,oDRAM1_LDQM0}) ); assign oUART_TXD = iUART_RXD; I2C_CCD_Config u9 .iCLK(iCLK_50), .iRST_N(DLY_RST_1), .iEXPOSURE_ADJ(iKEY[1]), .iEXPOSURE_DEC_p(iSW[0]), .iMIRROR_SW(iSW[17]), // I2C Side .I2C_SCLK(GPIO_1[20]), .I2C_SDAT(GPIO_1[19]) ( // Host Side ); assign mVGA_R = Read_DATA2[9:0]; assign mVGA_G = {Read_DATA1[14:10],Read_DATA2[14:10]}; assign mVGA_B = Read_DATA1[9:0]; lcd_3wire_config u11 ( // Host Side .iCLK(iCLK_50), .iRST_n(DLY_RST_0), // 3 wire Side .o3WIRE_SCLK(ltm_sclk), .io3WIRE_SDAT(ltm_sda), .o3WIRE_SCEN(ltm_scen), .o3WIRE_BUSY_n(ltm_3wirebusy_n) ); //wire [7:0] ltm_r_sign; //wire [7:0] ltm_g_sign; //wire [7:0] ltm_b_sign; // // // LTM Red Data 8 Bits LTM Green Data 8 Bits LTM Blue Data 8 Bits //wire //wire //wire // // // LTM Red Data 8 Bits LTM Green Data 8 Bits LTM Blue Data 8 Bits //wire //wire //wire //wire //wire //wire assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign [7:0] [7:0] [7:0] ltm_r_input_sign; ltm_g_input_sign; ltm_b_input_sign; ltm_hd_input_sign; ltm_vd_input_sign; ltm_den_input_sign; ltm_hd_sign; ltm_vd_sign; ltm_den_sign; adc_penirq_n =GPIO_CLKIN_N0; adc_dout =GPIO_0[0]; adc_busy =GPIO_CLKIN_P0; GPIO_0[1] =adc_din; GPIO_0[2] =adc_ltm_sclk; GPIO_0[3] =ltm_b_sign[3]; GPIO_0[4] =ltm_b_sign[2]; GPIO_0[5] =ltm_b_sign[1]; GPIO_0[6] =ltm_b_sign[0]; GPIO_0[7] =ltm_nclk; GPIO_0[8] =ltm_den_sign; GPIO_0[9] =ltm_hd_sign; GPIO_0[10] =ltm_vd_sign; GPIO_0[11] =ltm_b_sign[4]; GPIO_0[12] =ltm_b_sign[5]; GPIO_0[13] =ltm_b_sign[6]; GPIO_CLKOUT_N0 =ltm_b_sign[7]; 103 assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign assign GPIO_0[14] GPIO_CLKOUT_P0 GPIO_0[15] GPIO_0[16] GPIO_0[17] GPIO_0[18] GPIO_0[19] GPIO_0[20] GPIO_0[21] GPIO_0[22] GPIO_0[23] GPIO_0[24] GPIO_0[25] GPIO_0[26] GPIO_0[27] GPIO_0[28] GPIO_0[29] GPIO_0[30] GPIO_0[31] =ltm_g_sign[0]; =ltm_g_sign[1]; =ltm_g_sign[2]; =ltm_g_sign[3]; =ltm_g_sign[4]; =ltm_g_sign[5]; =ltm_g_sign[6]; =ltm_g_sign[7]; =ltm_r_sign[0]; =ltm_r_sign[1]; =ltm_r_sign[2]; =ltm_r_sign[3]; =ltm_r_sign[4]; =ltm_r_sign[5]; =ltm_r_sign[6]; =ltm_r_sign[7]; =ltm_grst; =ltm_scen; =ltm_sda; assign ltm_grst = iKEY[0]; assign adc_ltm_sclk = ltm_sclk ; // Touch panel signal // wire wire wire wire wire wire wire wire wire // LTM Config//// wire wire wire wire ltm_nclk; // adc_dclk; adc_cs; adc_penirq_n; adc_busy; adc_din; adc_dout; adc_ltm_sclk; ltm_grst; LTM Clcok ltm_sclk; ltm_sda; ltm_scen; ltm_3wirebusy_n; //This instance was Create/Altered By SynMaker. //################################################################### LTM LTM( .ltm_hd(ltm_hd_sign), .ltm_vd(ltm_vd_sign), .ltm_den(ltm_den_sign), .ltm_b(ltm_b_sign), .ltm_r(ltm_r_sign), .ltm_g(ltm_g_sign), .ltm_b_input(ltm_b_input_sign), .ltm_r_input(ltm_r_input_sign), .ltm_g_input(ltm_g_input_sign), .ltm_hd_input(ltm_hd_input_sign), .ltm_vd_input(ltm_vd_input_sign), .ltm_den_input(ltm_den_input_sign) ); wire [31:0] ltm_hd_sign; wire [31:0] ltm_vd_sign; wire [31:0] ltm_den_sign; wire [31:0] ltm_b_sign; wire [31:0] ltm_r_sign; wire [31:0] ltm_g_sign; wire [31:0] ltm_b_input_sign; wire [31:0] ltm_r_input_sign; 104 wire [31:0] ltm_g_input_sign; wire [31:0] ltm_hd_input_sign; wire [31:0] ltm_vd_input_sign; wire [31:0] ltm_den_input_sign; touch_tcon touch_tcon( .oLCD_G(oLCD_G_sign), .oLCD_R(oLCD_R_sign), .oLCD_B(oLCD_B_sign), .oREAD_SDRAM_EN(oREAD_SDRAM_EN_sign), .oHD(oHD_sign), .oVD(oVD_sign), .oDEN(oDEN_sign), .iCLK(iCLK_sign), .iRST_n(iRST_n_sign), .iREAD_DATA1(iREAD_DATA1_sign), .iREAD_DATA2(iREAD_DATA2_sign) ); wire [31:0] oLCD_G_sign; wire [31:0] oLCD_R_sign; wire [31:0] oLCD_B_sign; wire [31:0] oREAD_SDRAM_EN_sign; wire [31:0] oHD_sign; wire [31:0] oVD_sign; wire [31:0] oDEN_sign; wire [31:0] iCLK_sign; wire [31:0] iRST_n_sign; wire [31:0] iREAD_DATA1_sign; wire [31:0] iREAD_DATA2_sign; TestSobelrun TestSobelrun( .TestSobelrunltm_b_input(TestSobelrunltm_b_input_sign), .TestSobelrunltm_r_input(TestSobelrunltm_r_input_sign), .TestSobelrunltm_g_input(TestSobelrunltm_g_input_sign), .TestSobelrunSobelfsobel_input_3(TestSobelrunSobelfsobel_input_3_sign), .TestSobelrunSobelfsobel_input_4(TestSobelrunSobelfsobel_input_4_sign), .TestSobelrunSobelfsobel_input_5(TestSobelrunSobelfsobel_input_5_sign), .TestSobelrunSobelsinal_cor_input_3(TestSobelrunSobelsinal_cor_input_3_sign), .TestSobelruniCLK(TestSobelruniCLK_sign), .TestSobelruniRST_n(TestSobelruniRST_n_sign), .TestSobelrunltm_b(TestSobelrunltm_b_sign), .TestSobelrunltm_r(TestSobelrunltm_r_sign), .TestSobelrunltm_g(TestSobelrunltm_g_sign), .TestSobelrunoLCD_G(TestSobelrunoLCD_G_sign), .TestSobelrunoLCD_R(TestSobelrunoLCD_R_sign), .TestSobelrunoLCD_B(TestSobelrunoLCD_B_sign), .TestSobelrunSobelfsobel_output_1(TestSobelrunSobelfsobel_output_1_sign), .TestSobelrunSobelsinal_cor_output_1(TestSobelrunSobelsinal_cor_output_1_sign) ); wire [31:0] TestSobelrunltm_b_input_sign; wire [31:0] TestSobelrunltm_r_input_sign; wire [31:0] TestSobelrunltm_g_input_sign; wire [31:0] TestSobelrunSobelfsobel_input_3_sign; wire [31:0] TestSobelrunSobelfsobel_input_4_sign; wire [31:0] TestSobelrunSobelfsobel_input_5_sign; wire [31:0] TestSobelrunSobelsinal_cor_input_3_sign; wire [31:0] TestSobelruniCLK_sign; wire [31:0] TestSobelruniRST_n_sign; wire [31:0] TestSobelrunltm_b_sign; wire [31:0] TestSobelrunltm_r_sign; wire [31:0] TestSobelrunltm_g_sign; wire [31:0] TestSobelrunoLCD_G_sign; wire [31:0] TestSobelrunoLCD_R_sign; wire [31:0] TestSobelrunoLCD_B_sign; wire [31:0] TestSobelrunSobelfsobel_output_1_sign; 105 wire [31:0] TestSobelrunSobelsinal_cor_output_1_sign; Sobel Sobel( .Sobelfsobel_output_1(Sobelfsobel_output_1_sign), .Sobelsinal_cor_output_1(Sobelsinal_cor_output_1_sign), .SobelfsobeliCLK(SobelfsobeliCLK_sign), .SobelfsobeliRST_n(SobelfsobeliRST_n_sign), .Sobelfsobel_input_3(Sobelfsobel_input_3_sign), .Sobelfsobel_input_4(Sobelfsobel_input_4_sign), .Sobelfsobel_input_5(Sobelfsobel_input_5_sign), .Sobelsinal_coriCLK(Sobelsinal_coriCLK_sign), .Sobelsinal_coriRST_n(Sobelsinal_coriRST_n_sign), .Sobelsinal_cor_input_3(Sobelsinal_cor_input_3_sign) ); wire [31:0] Sobelfsobel_output_1_sign; wire [31:0] Sobelsinal_cor_output_1_sign; wire [31:0] SobelfsobeliCLK_sign; wire [31:0] SobelfsobeliRST_n_sign; wire [31:0] Sobelfsobel_input_3_sign; wire [31:0] Sobelfsobel_input_4_sign; wire [31:0] Sobelfsobel_input_5_sign; wire [31:0] Sobelsinal_coriCLK_sign; wire [31:0] Sobelsinal_coriRST_n_sign; wire [31:0] Sobelsinal_cor_input_3_sign; assign ltm_nclk = SobelfsobeliCLK_sign; assign DLY_RST_2 = SobelfsobeliRST_n_sign; assign ltm_nclk = Sobelsinal_coriCLK_sign; assign DLY_RST_2 = Sobelsinal_coriRST_n_sign; assign ltm_nclk = iCLK_sign; assign DLY_RST_2 = iRST_n_sign; assign iREAD_DATA1_sign = Read_DATA1; assign iREAD_DATA2_sign = Read_DATA2; assign Read = oREAD_SDRAM_EN_sign; assign ltm_hd_input_sign = oHD_sign; assign ltm_vd_input_sign = oVD_sign; assign ltm_den_input_sign = oDEN_sign; assign ltm_b_input_sign = TestSobelrunltm_b_input_sign; assign ltm_r_input_sign = TestSobelrunltm_r_input_sign; assign ltm_g_input_sign = TestSobelrunltm_g_input_sign; assign ltm_b_sign = TestSobelrunltm_b_sign; assign ltm_r_sign = TestSobelrunltm_r_sign; assign ltm_g_sign = TestSobelrunltm_g_sign; assign oLCD_G_sign = TestSobelrunoLCD_G_sign; assign oLCD_R_sign = TestSobelrunoLCD_R_sign; assign oLCD_B_sign = TestSobelrunoLCD_B_sign; assign Sobelfsobel_output_1_sign = TestSobelrunSobelfsobel_output_1_sign; assign Sobelsinal_cor_output_1_sign = TestSobelrunSobelsinal_cor_output_1_sign; assign Sobelfsobel_input_3_sign = TestSobelrunSobelfsobel_input_3_sign; assign Sobelfsobel_input_4_sign = TestSobelrunSobelfsobel_input_4_sign; assign Sobelfsobel_input_5_sign = TestSobelrunSobelfsobel_input_5_sign; assign Sobelsinal_cor_input_3_sign = TestSobelrunSobelsinal_cor_input_3_sign; //################################################################### endmodule 106