UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR CURSO DE CIÊNCIA DA COMPUTAÇÃO µBIP: MICROCONTROLADOR BÁSICO PARA O ENSINO DE SISTEMAS EMBARCADOS Área de Arquitetura e Organização de Computadores por Maicon Carlos Pereira Cesar Albenes Zeferino, Dr. Orientador Itajaí (SC), julho de 2008 UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR CURSO DE CIÊNCIA DA COMPUTAÇÃO µBIP: MICROCONTROLADOR BÁSICO PARA O ENSINO DE SISTEMAS EMBARCADOS Área de Arquitetura e Organização de Computadores por Maicon Carlos Pereira Relatório apresentado à Banca Examinadora do Trabalho de Conclusão do Curso de Ciência da Computação para análise e aprovação. Orientador: Cesar Albenes Zeferino, Dr. Itajaí (SC), julho de 2008 DEDICATÓRIA A Deus. Aos meus pais (Alvino e Lourdes) por toda a educação, carinho e amor que sempre me deram, aos meus irmãos (Arnaldo e Alex) pelo incentivo, e a minha namorada (Leonella) pela compreensão e motivação. ii AGRADECIMENTOS A Deus pela minha existência e por tudo que tenho; Ao meu pai Alvino, que mesmo do seu jeito calado e preservado, sempre me demonstrou o apoio e a confiança que eu precisava; A minha mãe Lourdes, que sempre reza e torce por mim. A minha família que sempre me apoiou e me incentivou muito e por ser a minha maior fonte de referência; A minha namorada Leonella, por me apoiar, motivar e por sempre estar ao meu lado em horas difíceis dessa etapa da minha vida; Aos meus padrinhos que me acolheram durante este último ano; Aos meus amigos de faculdade e do LSED que me acompanharam todo esse tempo com muita alegria e prestígio; Ao meu orientador e professor Cesar, pelo conhecimento passado, pelas horas dispostas e pelo imenso incentivo e confiança; Ao professor Rafael L. Cancian, por me inserir na área de pesquisa em sistemas embarcados e pelos ensinamentos; Ao meu amigo Zé Pequeno que acompanhou de perto meu trabalho e sempre me ajudou; Ao meu amigo e chefe Ivan, pelas dicas, pela força e horas de trabalho liberadas para realização desse trabalho. iii SUMÁRIO LISTA DE ABREVIATURAS.................................................................vii LISTA DE FIGURAS................................................................................ix LISTA DE TABELAS ................................................................................ x RESUMO....................................................................................................xi ABSTRACT...............................................................................................xii 1 INTRODUÇÃO ...................................................................................... 1 1.1 PROBLEMATIZAÇÃO ..................................................................................... 2 1.1.1 Formulação do Problema ................................................................................. 2 1.1.2 Solução Proposta ............................................................................................... 2 1.2 OBJETIVOS ........................................................................................................ 3 1.2.1 Objetivo Geral ................................................................................................... 3 1.2.2 Objetivos Específicos ........................................................................................ 3 1.3 METODOLOGIA................................................................................................ 3 1.4 ESTRUTURA DO TRABALHO ....................................................................... 5 2 FUNDAMENTAÇÃO TEÓRICA ........................................................ 6 2.1 SISTEMAS EMBARCADOS ............................................................................. 6 2.1.1 Características de Sistemas Embarcados ....................................................... 7 2.1.2 Projeto de Sistemas Embarcados .................................................................... 7 2.1.3 Tecnologias de Processadores Embarcados ................................................... 9 2.1.4 Tecnologias de Circuito Integrado (CI) ........................................................ 11 2.1.5 Tecnologias de Projeto.................................................................................... 15 2.1.6 Linguagem de descrição de hardware e VHDL ........................................... 17 2.2 ARQUITETURA E ORGANIZAÇÃO DE COMPUTADORES ................. 18 2.2.1 Arquitetura ...................................................................................................... 18 2.2.2 Organização..................................................................................................... 22 2.3 PROCESSADOR BIP II ................................................................................... 25 2.3.1 Arquitetura do BIP II..................................................................................... 26 2.3.2 Organização do BIP II.................................................................................... 29 2.4 MICROCONTROLADORES .......................................................................... 31 2.4.1 Características de Microcontroladores......................................................... 31 2.5 ARCHC............................................................................................................... 38 2.5.1 Recursos da Arquitetura (AC_ARCH)......................................................... 39 2.5.2 Arquitetura do Conjunto de Instruções (AC_ISA) ..................................... 40 3 DESENVOLVIMENTO ...................................................................... 45 3.1 ANÁLISE DE REQUISITOS........................................................................... 45 3.2 ESPECIFICAÇÃO DA ARQUITETURA ...................................................... 47 3.2.1 Tamanho da Palavra e Tipo de Dados .......................................................... 47 iv 3.2.2 Espaços de Endereçamento............................................................................ 47 3.2.3 Registradores................................................................................................... 49 3.2.4 Formatos de Instrução.................................................................................... 50 3.2.5 Modos de Endereçamento .............................................................................. 50 3.2.6 Conjunto de Instruções................................................................................... 51 3.2.7 Resumo da Arquitetura µBIP........................................................................ 53 3.3 ESPECIFICAÇÃO DA ORGANIZAÇÃO ..................................................... 54 3.4 IMPLEMENTAÇÃO DO µBIP NO ARCHC ................................................ 62 3.4.1 Recursos da arquitetura ................................................................................. 62 3.4.2 Arquitetura do conjunto de instruções ......................................................... 62 3.4.3 Testes e Validações.......................................................................................... 68 3.4.4 Limitações ........................................................................................................ 70 3.4.5 Considerações sobre o uso do ArchC como ferramenta de projeto arquitetural ................................................................................................................ 71 3.5 IMPLEMENTAÇÃO DO MODELO VHDL ................................................. 71 3.5.1 Testes e Validação ........................................................................................... 73 3.5.2 Prototipação Física.......................................................................................... 81 4 CONCLUSÕES .................................................................................... 83 4.1 TRABALHOS FUTUROS................................................................................ 84 REFERÊNCIAS BIBLIOGRÁFICAS ................................................... 85 A DESCRIÇÃO DO PROCESSADOR BIP-II EM ARCHC.............. 89 A.1 RECURSOS DA ARQUITETURA ................................................................. 89 A.2 CONJUNTO DE INSTRUÇÕES ..................................................................... 89 A.3 COMPORTAMENTO DAS INSTRUÇÕES .................................................. 90 B QUESTIONÁRIO ................................................................................ 94 B.1. CARTA DE APRESENTAÇÃO ...................................................................... 94 B.2. TABULAÇÃO DOS RESULTADOS .............................................................. 98 C CONJUNTO DE INSTRUÇÕES DO µBIP ...................................... 99 C.1. CLASSE: CONTROLE .................................................................................... 99 C.2. CLASSE: ARMAZENAMENTO .................................................................... 99 C.3. CLASSE: CARGA........................................................................................... 100 C.4. CLASSE: ARITMÉTICA............................................................................... 101 C.5. CLASSE: LÓGICA BOOLEANA ................................................................. 103 C.6. CLASSE: DESVIO .......................................................................................... 106 C.7. CLASSE: DESLOCAMENTO LÓGICO ..................................................... 110 C.8. CLASSE: MANIPULAÇÃO DE VETOR .................................................... 111 C.9. CLASSE: SUPORTE A PROCEDIMENTOS ............................................. 112 D INSTALAÇÃO DO ARCHC ............................................................114 D.1. OBTENDO OS ARQUIVOS DE INSTALAÇÃO........................................ 114 D.2. INSTALAR O SYSTEMC .............................................................................. 115 v D.3. INSTALAR O ARCHC................................................................................... 116 D.4. GERANDO O MONTADOR ......................................................................... 116 D.5. UTILIZANDO O MONTADOR .................................................................... 117 D.6. GERANDO O SIMULADOR......................................................................... 117 D.7. UTILIZANDO O SIMULADOR ................................................................... 118 D.8. UTILIZANDO O LIGADOR ......................................................................... 118 E F G H PLANO DE TESTE UNITÁRIO......................................................119 TESTBENCH (DALTON-PROJECT) ............................................125 BLOCOS VHDL.................................................................................135 REGISTRADORES ...........................................................................145 vi LISTA DE ABREVIATURAS µBIP A/D ABEL ABS ACC ADL AHDL ALU ASIC ASIP BIP CI CISC CPU DIP DSP E/S EEPROM EPROM FPGA FSM HDL I2C IC IC-UNICAMP INDR IP IPR ISA LIFO LSED MIPS MHz MP3 NRE PC PC PDA PIC PLCC PLD PROM PWM RAM RI RISC microBIP Analógico-Digital Advanced Boolean Expression Language Anti-Blocking System Acumulador Architecture Description Language Altera Hardware Description Languages Arithmetic-Logic Unit Application-Specific Integrated Circuit Application-Specific Instruction-set Processor Basic Instruction-set Processor Circuito Integrado Complex Instruction Set Computers Central Processing Unit Dual-in-line Package Digital Signal Processor Entrada/Saída Electrically EPROM Erasable PROM Field Programmable Gate Arrays Finite State Machine Hardware Description Languages Inter-Integrated Circuit Interrupt Controller Instituto de Computação da Universidade de Campinas Index Register Intellectual Property Interrupt Pending Register Instruction Set Architecture Last In First Out Laboratório de Sistemas Embarcados e Distribuídos Microprocessor without Interlocked Pipeline Stages Mega Hertz Moving Picture Experts Group -1/2 Audio Layer 3 Non-Recurring Engineering Cost Program Counter Personal Computer Personal Digital Assistant Programmable Intelligent Computer Plastic Leadless Chip Carrier Programmable Logic Device Programmable ROM Pulse Width Modulator Random Access Memory Registrador de Instrução Reduced Instruction Set Computer vii ROM RF RNF RT RX SFR SMD SOP SPI TCC TOS TX UF ULA UNIVALI VHDL VHSIC VLSI Read Only Memory Requisito Funcional Requisito Não Funcional Register-Transfer Receptor Special Function Register Surface Mounted Devices Small Outline Package Serial Peripheral Interface Trabalho de Conclusão de Curso Top of Stack Transmissor Unidade Funcional Unidade Lógica Aritmética Universidade do Vale do Itajaí VHSIC Hardware Description Language Very High-Speed Integrated Circuits Very Large Scale Integration viii LISTA DE FIGURAS Figura 1. Lançamento do produto x retorno financeiro .......................................................................9 Figura 2. Tecnologias de processadores para a implementação de uma funcionalidade .....................9 Figura 3. Visão abstrata da organização de uma FPGA.....................................................................14 Figura 4. Comparativo entre as Tecnologias de CI............................................................................14 Figura 5. Fonte dos operando nas diferentes classes de conjunto de instruções. ...............................19 Figura 6. Arquitetura de Memória......................................................................................................24 Figura 7. Métricas da hierarquia de memória ....................................................................................25 Figura 8. Organização do Processador BIP II ....................................................................................29 Figura 9. Sistemas de Interligação Digitais. TX (Transmissor) e RX (Receptor) .............................34 Figura 10. Descrição dos Recursos para o processador BIP-II ..........................................................39 Figura 11. Descrição parcial do conjunto de instrução para o processador BIP-II............................42 Figura 12. Descrição parcial do comportamento do conjunto de instrução do processador BIP-II...44 Figura 13. Espaçamento de Memória no µBIP ..................................................................................48 Figura 14. Organização da Memória de E/S ......................................................................................49 Figura 15. Formato de instrução no µBIP ..........................................................................................50 Figura 16. Modo de endereçamento Indireto .....................................................................................51 Figura 17. Visão abstrata da organização do µBIP ............................................................................54 Figura 18. Visão detalhada da organização da CPU do µBIP............................................................55 Figura 19. Organização da Unidade Funcional do µBIP ...................................................................56 Figura 20. Organização da Pilha ........................................................................................................57 Figura 21. Organização do módulo de manipulação de vetores ........................................................58 Figura 22. Fluxo do Controle de Interrupção .....................................................................................60 Figura 23. Integração da CPU com os periféricos e Memórias. ........................................................61 Figura 24. Implementação do µBIP no ArchC – Recursos da Arquitetura........................................62 Figura 25. Implementação do µBIP no ArchC – ubip_isa.ac ............................................................63 Figura 26. Implementação do µBIP no ArchC – Funções Auxiliares (ubip_isa.cpp)........................65 Figura 27. Implementação do µBIP no ArchC – Comportamento (ubip_isa.cpp).............................66 Figura 28. Implementação do µBIP no ArchC – Arquivo de Simulação (ubip_isa.cpp)...................67 Figura 29. Implementação do µBIP no ArchC – Processo de Simulação..........................................68 Figura 30. Utilização das instruções nos testbenchs ..........................................................................70 Figura 31. Visão top-down do µBIP ..................................................................................................72 Figura 32. Hierarquia de arquivos VHDL..........................................................................................73 Figura 33. Diagrama de formas de onda da simulação da execução da aplicação cast .....................74 Figura 34. Diagrama de formas de onda da simulação da execução da aplicação fib .......................75 Figura 35. Diagrama de formas de onda da simulação da execução da aplicação Exemplo 5 Parte-1 ....................................................................................................................................................76 Figura 36. Diagrama de formas de onda da simulação da execução da aplicação Exemplo 5 Parte-2 ....................................................................................................................................................77 Figura 37. Custo por bloco da aplicação Exemplo 5 ..........................................................................79 Figura 38. Kit de prototipação Altera® UP-2 ....................................................................................81 ix LISTA DE TABELAS Tabela 1. Arquitetura do BIP II..........................................................................................................27 Tabela 2. Conjunto de instruções do BIP II .......................................................................................28 Tabela 3. Tabela de decodificação de instrução.................................................................................30 Tabela 4. Características de Microcontroladores comerciais.............................................................37 Tabela 5. Conjunto de instruções do µBIP.........................................................................................52 Tabela 6. Arquitetura do µBIP ...........................................................................................................53 Tabela 7. Código de operação da Unidade Funcional........................................................................56 Tabela 8. Configuração do prescaler no registrador tmr0_config ...............................................59 Tabela 9. Descrição do testbench .......................................................................................................69 Tabela 10. Custo das Aplicações na FPGA FLEX10K-EPF10K70RC240-4 ...................................78 Tabela 11. Análise de tempo na FPGA FLEX10K-EPF10K70RC240-4 .........................................80 Tabela 12. Configuração de pinagem para prototipação no kit UP-2 ...............................................82 Tabela 13. Tabulação dos Dados Coletados.......................................................................................98 x RESUMO PEREIRA, Maicon C. µBIP: Microcontrolador básico para o ensino de Sistemas Embarcados. Itajaí, 2008. 161f. Trabalho de Conclusão de Curso (Graduação em Ciência da Computação)– Centro de Ciências Tecnológicas da Terra e do Mar, Universidade do Vale do Itajaí, Itajaí, 2008. O ensino de conceitos introdutórios em disciplinas-base para a formação de profissionais aptos ao desenvolvimento de sistemas embarcados requer inicialmente a utilização de arquiteturas simples o suficiente para que o aluno possa relacionar os conceitos de arquitetura e organização de computadores com conceitos de programação. Nesse contexto, uma família de processadores, denominada BIP – Basic Instruction-set Processor, foi desenvolvida por pesquisadores do Laboratório de Sistemas Embarcados e Distribuídos da Universidade do Vale do Itajaí para apoio no ensino em disciplinas de fases iniciais do curso de Ciência da Computação. Duas versões foram especificadas oferecendo suporte à conceitos tratados nessas disciplinas. No entanto, os recursos desses processadores são limitados para sua aplicação em disciplinas mais avançadas como, por exemplo, as que abordem a aplicação de processadores em tarefas de controle. Neste sentido, este Trabalho de Conclusão de Curso (TCC) apresenta o desenvolvimento de um microcontrolador denominado µBIP, que estende as características presentes no projeto BIP, agregando periféricos e funcionalidades típicas de microcontroladores. Este trabalho disponibiliza uma especificação de processador e ferramentas de apoio ao ensino de várias disciplinas como Arquitetura e Organização de Computadores, Sistemas Embarcados, Circuitos Digitais, Compiladores e Programação em cursos de graduação em Ciência da Computação e em Engenharia de Computação. Neste texto, é apresentada uma revisão de conceitos-base associados ao desenvolvimento de sistemas embarcados e de processadores, assim como o projeto e implementação do microcontrolador µBIP e suas ferramentas. Palavras-chave: Sistemas Microcontroladores. Embarcados. Arquitetura xi e Organização de Computadores. ABSTRACT The teaching of introductory concepts in base disciplines for the formation of professionals that are capable of developing embedded systems initially requires the utilization of simple enough architectures so that the student can relate the concepts of computer architecture and organization with programming concepts. In this context, a family of processors, called BIP - Basic Instructionset Processor, was developed by researchers of Embedded and Distributed Systems Laboratory of University of Vale do Itajaí – UNIVALI for learning support in initial phases of the Computer Science major. Two versions were specified, offering support to concepts that are taught in this major. However, these processors resources are limited for their application in more advanced disciplines like, for example, those which approach the application of processors in control tasks. In this sense, this final work presents the development of a microcontroller named µBIP, which extends the features of BIP architecture, adding peripherals and functionalities typically found in commercial microcontrollers. This work makes possible to apply the processor specification, and related tools, to support the teaching of various disciplines such as Computer Architecture and Organization, Embedded Systems, Digital Circuits, Compilers, and Programming in Computer Science and Computer Engineer courses. In this text, it is presented a study on concepts needed for the development of embedded systems and processors, such as the design and implementation of µBIP microcontroller and its tools. Keywords: Embedded Systems. Computer Architecture and Organization. Microcontrollers. xii 1 INTRODUÇÃO Sistemas embarcados estão a cada dia mais presentes no cotidiano das pessoas, executando atividades de processamento e/ou de controle nos mais diversos tipos de produtos e equipamentos, como em automóveis, aparelhos televisores, tocadores de MP3 (Moving Picture Experts Group -1/2 Audio Layer 3), câmeras digitais e telefones celulares, entre outros. O aumento da demanda por produtos baseados em sistemas embarcados tem levado à necessidade de profissionais capazes de atuar nas diferentes fases do projeto desses sistemas. Porém, os cursos de graduação na área da Computação não estão atendendo à essa necessidade e precisam suprir uma base maior de conceitos dirigidos a esse domínio de aplicação que possui restrições e requisitos diferentes de computadores de uso geral como os PCs (Personal Computer) (HENZINGER; SIFAKIS, 2007). As disciplinas da área de Arquitetura e Organização de Computadores são fundamentais na formação de alunos nos cursos de graduação em Ciência da Computação e em Engenharia de Computação, especialmente para aqueles que seguirão uma linha dirigida ao desenvolvimento de sistemas embarcados. Entretanto muitos alunos apresentam grandes dificuldades no entendimento de conceitos apresentados nas primeiras aulas dessas disciplinas. Por esse motivo, professores estão em constante busca por métodos que auxiliem o aluno a compreender os conceitos de arquitetura e organização de computadores fazendo uma ligação com os conceitos apresentados em disciplinas como de programação, compiladores e outras. Neste sentido, professores utilizam de diversos modelos de processadores para servir de referência ao estudo da arquitetura e da organização de processadores, os quais vão desde arquiteturas básicas como o Neander, o Cesar e o Ramses (WEBER, 2004), a arquiteturas mais complexas como o MIPS (Microprocessor without Interlocked Pipeline Stages) (PATTERSON; HANESSY, 2000). Uma iniciativa nesse sentido é o BIP (Basic Instruction-set Processor), um processador cuja arquitetura foi projetada visando atender aos seguintes objetivos: • Facilitar o aprendizado de conceitos introdutórios de arquitetura e de organização de computadores em fases iniciais de cursos de graduação na área de Computação; e • Facilitar a aplicação do BIP em disciplinas relacionadas a área de Sistemas de Computação e promover a integração interdisciplinar. O BIP foi desenvolvido por pesquisadores do Laboratório de Sistemas Embarcados e Distribuídos do Curso de Ciência da Computação da Universidade do Vale do Itajaí – Univali, sendo que duas versões já foram implementadas. O BIP I (MORANDI et al., 2006) possui um conjunto de instruções limitado a operações aritméticas básicas (soma e subtração) e de transferência de dados entre o processador e a memória. O BIP II (MORANDI; RAABE; ZEFERINO, 2006) estendeu essa arquitetura incluindo instruções de desvio condicional e incondicional para a implementação de estruturas de controle, como laços de repetição. O BIP já foi aplicado em diferentes disciplinas dos seguintes cursos de graduação e de pósgraduação da Univali: • Curso de Graduação em Ciência da Computação (Itajaí): Computação Básica, Circuitos Digitais, Arquitetura e Organização de Computadores e Compiladores; • Curso de Graduação em Engenharia de Computação (São José): Tópicos Especiais em Engenharia de Computação: Sistemas Embarcados; e • Curso de Mestrado em Computação Aplicada (São José): Arquitetura de Computadores e Projeto de Sistemas Digitais. Sua utilização nesses cursos permitiu confirmar a efetividade da abordagem utilizada, pois os objetivos desejados foram atingidos. 1.1 PROBLEMATIZAÇÃO 1.1.1 Formulação do Problema A aplicabilidade do BIP em disciplinas mais avançadas, com foco no projeto de componentes para sistemas embarcados, mostrou-se muito limitada, pois a versão atual da arquitetura (BIP II) não contempla características de processadores reais, especialmente aqueles utilizados em sistemas embarcados. Por exemplo, o BIP não possui interface de entrada-e-saída, e nenhum tipo de periférico comumente encontrado em processadores para tais sistemas. 1.1.2 Solução Proposta A solução proposta neste projeto consiste em estender a arquitetura do BIP, de modo a especificar um conjunto de instruções mais completo compatível com o de arquiteturas usadas no 2 ensino de sistemas embarcados, e disponibilizar uma implementação física desse processador com periféricos básicos utilizados em microcontroladores, como portas de entrada-e-saída, controlador de interrupções e um temporizador. Por isso, essa nova versão será denominada µBIP (lê-se micro BIP). Embora o desenvolvimento deste projeto se justifique na sua futura aplicação no ensino, considerando as limitações de tempo, o presente trabalho não avaliará o impacto do uso µBIP em cursos de graduação e/ou de pós-graduação. 1.2 OBJETIVOS 1.2.1 Objetivo Geral O objetivo geral deste trabalho é desenvolver um modelo de microcontrolador com arquitetura simplificada visando sua aplicação no ensino de graduação e de pós-graduação. 1.2.2 Objetivos Específicos Os objetivos específicos deste projeto são: • Consolidar conceitos sobre sistemas embarcados; • Consolidar conceitos de arquitetura e organização de computadores; • Analisar arquiteturas de microcontroladores para identificar características comuns que devam ser incluídas no µBIP; • Compreender as tecnologias a serem utilizadas no desenvolvimento do µBIP; • Disponibilizar modelos de simulação e de síntese do µBIP; • Disponibilizar montador e ligador para µBIP; • Testar e validar a implementação do modelo por simulação e em protótipo físico; e • Documentar e divulgar o projeto. 1.3 METODOLOGIA A metodologia adotada nesse Trabalho de Conclusão de Curso (TCC) é dividida em seis partes: 3 • Estudo: Nessa etapa foram realizados estudos e práticas a fim de adquirir os conhecimentos necessários para a realização desse trabalho. Para o estudo foram utilizados livros, manuais e datasheets. Também foram realizadas atividades práticas com o ArchC com o objetivo de entender melhor o ambiente e seus recursos. • Modelagem: Nessa etapa foram realizadas as especificações e o projeto da arquitetura e organização do µBIP, além de uma pesquisa realizada para ajudar a definir os requisitos do projeto. • Revisão do projeto: nesta etapa foi realizada a revisão desse trabalho levando em consideração as questões levantas pelos membros avaliadores da banca. • Desenvolvimento: Nessa etapa foram realizadas as implementações das especificações levantadas na etapa de modelagem, sendo: 1. Modelagem da Arquitetura do conjunto de instrução (ISA) no ArchC; 2. Geração do simulador do ISA; 3. Geração do Montador do ISA; 4. Refinamento do projeto da organização do µBIP; 5. Modelagem VHDL do µBIP; e 6. Síntese e prototipação do modelo em FPGA. • Validação: Nessa etapa foram realizados testes e experimentação nos modelos desenvolvidos. Ela se sobrepôs à etapa de implementação, durante os testes dos componentes, e se estendeu até o teste de integração. Algumas das atividades desenvolvidas nessa etapa foram: 1. Implementação de aplicações de teste para a validação da arquitetura; 2. Validação por simulação; 3. Validação física em Kit de desenvolvimento para FPGA da Altera® (disponível no LSED); • Documentação: Nessa etapa foi realizada a documentação de todo o processo existente no trabalho, desde a descrição do problema, a proposta de uma solução, a implementação da solução, os testes, validações e os resultados finais. Essa etapa incluiu 4 também a produção e publicação de um artigo científico para divulgação da pesquisa realizada. 1.4 ESTRUTURA DO TRABALHO Este documento está dividido em quatro capítulos. O Capítulo 1, Introdução, apresentou uma visão inicial sobre o tema abordado no trabalho bem como seus objetivos. O Capítulo 2, Fundamentação Teórica, apresenta o resultado da etapa de estudo, com uma revisão bibliográfica dos temas envolvidos no trabalho. O Capítulo 3, Desenvolvimento, apresenta o projeto e a implementação do projeto em questão. O último capítulo apresenta as conclusões sobre o trabalho. O documento também inclui oito apêndices que complementam o conteúdo deste trabalho. 5 2 FUNDAMENTAÇÃO TEÓRICA Neste capítulo é apresentada a revisão bibliográfica sobre os temas envolvidos no projeto. A Seção 2.1 apresenta uma visão sobre sistemas embarcados, expondo suas características e tecnologias. Na Seção 2.2 é apresentada uma breve revisão sobre Arquitetura e Organização de Computadores, já que este tema é discutido durante o curso. A Seção 2.3 apresenta informações sobre a arquitetura e organização do processador BIP II. Na Seção 2.4 é apresentado um levantamento das características de microcontroladores. Finalizando este capítulo, a Seção 2.5 apresenta informações sobre o ArchC, uma das tecnologias utilizadas neste projeto. 2.1 Sistemas Embarcados Vahid e Givargis (2002, p. 1) definem um sistema computacional embarcado, ou apenas sistema embarcado, como qualquer sistema computacional exceto pelos desktops, laptops ou mainframes. Já Wolf (2002) define sistema embarcado como “qualquer computador que é um componente de um sistema maior”. Sistemas embarcados são construídos há décadas. Porém, os microprocessadores mais antigos se limitavam a executar a função básica no controle de dispositivos de entrada e saída (WOLF, 2002). Sistemas computacionais embarcados estão em toda parte e tendem a aumentar sua presença ainda mais, devido ao baixo custo tecnológico atual (CARRO; WAGNER, 2003). Vahid e Givargis (2002, p. 1-2) apresentam uma variedade de dispositivos eletrônicos comuns que possuem sistemas embarcados: 1. Eletrônicos pessoais: celulares, pagers, câmeras digitais, câmeras de vídeo, videocassetes, video-games portáteis, calculadoras, e PDAs (Personal Digital Assistant – Assistente Digital Pessoal); 2. Eletrodomésticos: forno de microondas, secretária eletrônica, termostato, segurança residencial, máquinas de lavar e sistemas de iluminação; 3. Escritório: fax, copiadoras, impressoras e scanners; 4. Equipamentos comerciais: caixa registradora, controle de estacionamento, sistemas de alarme, leitores de cartão, leitores de código de barras; e 5. Automóveis: controle de transmissão, controle de trajeto, injeção eletrônica, freios ABS (Anti-Blocking System) e suspensão ativa. 2.1.1 Características de Sistemas Embarcados Segundo Vahid e Givargis (2002, p. 2-3), sistemas embarcados apresentam algumas características especificas que os diferem de outros sistemas computacionais: 1. Monofuncional: usualmente, sistemas embarcados são projetados para executar repetidamente apenas um programa. Entretanto existem algumas exceções como, por exemplo, telefones celulares que permitem a execução de diversos aplicativos, além da inclusão de outros; 2. Restrições de Projeto: o projeto de sistemas embarcados, assim como o projeto de sistemas computacionais, possui uma série de limitações. Porém, no projeto de sistemas embarcados, essas limitações são maiores. Sistemas embarcados normalmente possuem baixo custo, tamanho reduzido, desempenho para processamento em tempo-real e baixo consumo de energia; e 3. Reativos em Tempo-Real: Muitos dos sistemas embarcados devem reagir às mudanças do ambiente e processar dados em tempo-real sem atraso. 2.1.2 Projeto de Sistemas Embarcados Projetar um sistema embarcado que cumpra as suas funcionalidades e que otimize simultaneamente várias métricas de projeto é considerado um desafio (CARRO; WAGNER, 2003; VAHID; GIVARGIS, 2002). Algumas métricas de projeto são apresentadas por Vahid e Givargis (2002, p. 5): 1. Custo NRE (Non-Recurring Engineering Cost - custo de engenharia não-recorrente): custo monetário de projetar o sistema. Segundo Carro e Wagner (2003) o projeto de um sistema embarcado complexo resulta em um custo alto devido à necessidade de equipes multidisciplinares (hardware digital, hardware analógico, software, teste), além da utilização de ferramentas computacionais caras; 7 2. Custo Unitário: custo monetário de produção para cada cópia do sistema, exceto pelo custo NRE; 3. Tamanho: Espaço físico requerido pelo sistema. Freqüentemente, medido em bytes ou bits para software e portas ou transistores para hardware; 4. Desempenho: Tempo de execução ou vazão do sistema; 5. Energia: Quantidade de energia consumida pelo sistema; 6. Flexibilidade: refere-se à habilidade de mudanças nas funcionalidades do sistema sem acarretar em novos custos de NRE; 7. Time-to-market (tempo para mercado): Quantidade de tempo requerido para projetar, produzir e lançar o sistema no mercado; 8. Tempo de prototipação: Quantidade de tempo para a construção de uma versão de trabalho do sistema; 9. Corretude ou correção: Garantia de que a funcionalidade do sistema foi implementada corretamente; e 10. Segurança: refere-se à probabilidade de que o sistema não causará danos; entre outras. Segundo esses autores, essas métricas competem entre si, e a melhoria em uma delas pode acarretar em prejuízos a outras métricas. Carro e Wagner (2003) e Vahid e Givargis (2002, p. 5-6) afirmam que uma otimização da métrica time-to-market tem sido exigida cada vez mais. Isso implica no projeto de novos sistemas embarcados com janelas de tempo cada vez menores. Como mostra a Figura 1, o atraso no lançamento de um produto compromete o seu retorno financeiro esperado. Na figura, a área sombreada representa os rendimentos perdidos pela entrada em atraso no mercado. 8 Figura 1. Lançamento do produto x retorno financeiro Fonte: Carro e Wagner (2003). 2.1.3 Tecnologias de Processadores Embarcados “A tecnologia de processadores envolve a arquitetura do mecanismo computacional usada para implementar uma funcionalidade desejada do sistema” (VAHID; GIVARGIS, 2002, p. 9). Figura 2. Tecnologias de processadores para a implementação de uma funcionalidade Fonte: Adaptado de Vahid e Givargis (2002, p. 10). 9 As subseções a seguir descrevem três tecnologias de processadores: (a) processador de propósito geral; (b) processador de propósito único; e (c) processador de aplicação específica. A Figura 2 (a) apresenta a funcionalidade desejada de um sistema que será analisada e comparada com as diferentes tecnologias de processadores. A funcionalidade consiste em somar os itens de um vetor e armazenar o total. 2.1.3.1 Processador de Propósito Geral “O projetista de um processador de propósito geral constrói um dispositivo apropriado para uma variedade de aplicações, para maximizar o número de dispositivos vendidos” (VAHID; GIVARGIS, 2002, p. 9). Processadores de propósito geral, também conhecidos como microprocessadores e CPU (Central Processing Unit – Unidade Central de Processamento), possuem características comuns como: (a) presença de uma memória de programa em que é armazenada um programa com funcionalidade desejada; (b) caminho de dados (datapath) genérico o bastante para manipular uma variedade de computação; e (c) possuem um banco de registrador grande e uma ou mais ALU (Arithmetic-Logic Unit - Unidade Lógica Aritmética - ULA) de propósito geral. Ao utilizar-se desta tecnologia, o projetista se beneficia em algumas métricas de projeto como: (a) flexibilidade alta, já que alterações nas funcionalidades são realizadas apenas no código do programa; (b) custo NRE e time-to-market são baixos, pois o projetista deve apenas escrever o código do programa; (c) custo unitário pode ser relativamente baixo para pequenas quantidades; e (d) desempenho alto para aplicações de computação-intensiva. Em contrapartida, há desvantagens, como: (i) custo unitário pode ser alto em grande escala; e (ii) tamanho grande e consumo de energia é alto (VAHID; GIVARGIS, 2002, p.10) Considerando a representação apresentada previamente na Figura 2, um microprocessador possui mais recursos do que o necessário para realizar a funcionalidade desejada (Figura 2 (b)). Logo, um microprocessador pode executar a função, mas não necessariamente de forma eficiente. 2.1.3.2 Processador de Propósito Único “Um processador de propósito único é um circuito digital projetado para executar exatamente um programa” (VAHID; GIVARGIS, 2002, p. 10). A funcionalidade nesse tipo de 10 processador é implementada diretamente no hardware, e é também conhecido como processador dedicado, co-processador ou acelerador. Em processadores dedicados alcançam-se benefícios em métricas de projetos como tamanho reduzido, baixo consumo de energia, custo unitário baixo para grandes quantidades e alto desempenho na grande maioria dos projetos. Por outro lado, o custo NRE e o tempo de projeto são altos, a flexibilidade é baixa e o custo unitário é alto para poucas quantidades. Dada a funcionalidade apresentada na Figura 2 (a), o uso de processadores dedicados nesta funcionalidade representa exatamente a funcionalidade desejada (Figura 2 (d)). 2.1.3.3 Processador de Aplicação Específica Segundo Vahid e Givargis (2002, p. 12), um processador de aplicação específica (ASIP - Application-Specific Instruction-set Processor) é um meio termo entre os dois processadores anteriores. O projeto de um ASIP segue uma classe de aplicações com características comuns, tais como DSPs (Digital Signal Processor, Processador de Sinal Digital), em telecomunicações e outros. No projeto de um ASIP, o projetista acrescenta algumas unidades funcionais para operações comuns e elimina outras unidades que normalmente não são utilizadas. As vantagens desta tecnologia referente às métricas de projeto são a flexibilidade e o desempenho satisfatório, além do tamanho reduzido e do baixo consumo de energia. A desvantagem é o alto custo NRE para construir o próprio processador e o compilador, se estes não existirem. Dada a funcionalidade apresentada na Figura 2 (a), o uso de processadores de aplicação específica (Figura 2 (c)) se aproxima mais da funcionalidade desejada do que o de propósito geral. 2.1.4 Tecnologias de Circuito Integrado (CI) Segundo Vahid e Givargis (2002, p. 13), Circuito Integrado, também conhecido como “chip” ou simplesmente CI, é um dispositivo semicondutor composto por vários transistores conectados e outros componentes que realizam uma função. O autor afirma que “Todo o processador deve ser implementado em um circuito integrado”. A implementação de um processador é independente da tecnologia de CI. Logo, qualquer tecnologia de processador pode ser mapeada em qualquer tipo de tecnologia de CI. 11 Segundo Vahid e Givargis (2002, p. 13), para compreender as diferenças entre as diversas tecnologias de CIs, é necessário primeiramente reconhecer as camadas que compõe um CI, sendo: (i) camadas inferiores, compostas de transistores; (ii) camadas centrais, compostas de portas lógicas; e (iii) camadas superiores, que conectam as portas lógicas com os contatos. Reconhecer as camadas se faz necessário, pois a diferença entre as tecnologias está na forma como estas camadas são disponibilizadas pelo fabricante. 2.1.4.1 Full-Custom/VLSI Na tecnologia Full-Custom, também referenciada por VLSI (Very Large Scale Integration, Integração em Larga Escala), todas as camadas devem ser otimizadas para a aplicação específica com a construção das máscaras necessárias para a fabricação do dispositivo real. Algumas das otimizações possíveis incluem o posicionamento e dimensionamento dos transistores, assim como o roteamento dos fios (VAHID; GIVARGIS, 2002, p. 13). Segundo Güntzel (2002, p.78), o termo Full-Custom está para “Sob-medida”, ou seja, todos os elementos são definidos. A utilização da tecnologia Full-Custom resulta em vantagens como (a) desempenho excelente; (b) tamanho reduzido e (c) baixo consumo. Porém resulta em desvantagens como: (a) alto custo NRE; e (b) longo time-to-market. (GÜNTZEL, 2002, p. 78; VAHID; GIVARGIS, 2002, p. 13). Güntzel (2002, p.78) apresenta como exemplo de CIs baseados na tecnologia Full-Custom microprocessadores, microcontroladores comerciais, circuitos para equipamentos portáteis como celulares e circuitos para aviões e satélites. Segundo Vahid e Givargis (2002, p.13), a tecnologia Full-Custom é normalmente aplicada em situações de grande volume e/ou onde o desempenho é crítico. 2.1.4.2 Semi-Custom/ASIC Segundo Güntzel (2002, p.78) e Vahid e Givargis (2002, p.13), na tecnologia Semi-Custom, tipicamente referenciada por ASIC (Application-Specific Integrated Circuit – Circuito Integrado de Aplicação Específica), as camadas inferiores são completamente ou parcialmente construídas 12 previamente, e o projetista deve apenas posicionar alguns blocos e realizar o roteamento das interconexões. Exemplos de tecnologia ASIC incluem os Gate Arrays1 e as Standard Cells2. Esta tecnologia possui a vantagem de ter um custo NRE menor que na tecnologia FullCustom e ainda apresentar boas métricas de desempenho e tamanho (GÜNTZEL, 2002, p. 78; VAHID; GIVARGIS, 2002, p. 14). 2.1.4.3 Lógica programável/PLD Segundo Brown e Vranesic (2000, p. 81), PLD (Programmable Logic Device, Dispositivo de Lógica Programável) é um chip de propósito geral que possui um conjunto de circuitos lógicos que permite o usuário personalizar o hardware. Com respeito às camadas de circuito, de acordo com Vahid e Givargis (2002, p. 14) na tecnologia PLD, todas as camadas já estão construídas, bastando apenas configurar as conexões entre as portas lógicas para implementar a funcionalidade desejada. Segundo Güntzel (2002, p.80), PLD são exemplos de componentes personalizáveis após o encapsulamento. Existem vários tipos de PLDs, os mais populares são os FPGAs (Field Programmable Gate Arrays), que oferecem mais conectividade entre os blocos lógicos, além de permitirem a implementação de projetos mais complexos. (BROWN; VRANESIC, 2000, p. 92; MENDONÇA; ZELENOVSKY, 2004, p. 265-266; VAHID; GIVARGIS, 2002, p. 14). A Figura 3 apresenta uma visão abstrata da organização de uma FPGA que conforme Brown e Vranesic possuem três elementos básicos: (i) blocos lógicos que possuem os circuitos lógicos; (ii) blocos de E/S; e (iii) barramento de interconexão e seletores. Segundo Vahid e Givargis (2002, p. 14) esta tecnologia tem um custo NRE muito baixo, porém tem um tamanho grande, desempenho inferior a ASICs e VLSIs, alto consumo de energia, além de custo unitário maior em relação aos anteriores. 1 Todas portas lógicas do CI já foram definidos com o seu posicionamento sobre um CI já conhecidos, deixando para o projetista com a tarefa de ligar as portas da maneira desejada. (VAHID; GIVARGIS, 2002, p. 276). 2 Arranjo de blocos lógicos padronizados disponibilizados em forma de bibliotecas de células lógicas (MELO; RIOS; GUTIERREZ, 2001, p. 11). 13 Figura 3. Visão abstrata da organização de uma FPGA Fonte: Adaptado de Brown e Vranesic (2000, p. 93) A Figura 4 compara as tecnologias de CI por métricas projeto como (a) densidade lógica, quantidade de lógica que pode ser colocada em um circuito, (b) desempenho, (c) custo unitário e (d) tempo de prototipação. Na figura, cada seta aponta na direção do aumento da métrica. Densidade Lógica Desempenho Custo Unitário Tempo de Prototipação Full-Custom Semi-Custom Figura 4. Comparativo entre as Tecnologias de CI. Fonte: Adaptado de Güntzel (2002, p.81) 14 PLD 2.1.5 Tecnologias de Projeto Conforme Vahid e Givargis (2002, p. 16), “a tecnologia de projeto envolve a maneira na qual nós convertemos nosso conceito de uma funcionalidade desejada em uma implementação”. Devem-se otimizar as métricas de projeto, principalmente reduzindo o tempo para sua realização. Os autores explicam que uma forma de melhorar o processo de projeto está em entender como ele funciona e uma maneira para este objetivo é através da técnica de projeto top-down, no qual o sistema é visto em diversos níveis de abstração. Em um nível mais superior, nível de sistema, o projetista descreve a funcionalidade em uma linguagem, preferencialmente em uma linguagem executável. Este processo é chamado de “especificação do sistema”. Após esse processo, o projetista distribui partes desta especificação entre os processadores escolhidos (de propósito geral ou único), resultando em uma “especificação de comportamento” para cada processador. O projetista então refina estas especificações em “especificações no nível RT” (Register-Transfer transferência entre registradores), realizando a conversão do comportamento do processador de propósito geral em código assembly e o comportamento do processador de propósito único em conexões de componentes RT3 e máquinas de estado. O projetista então refina as especificações RT em “especificações lógicas”, compostas de equações booleanas. Por fim, são refinadas as especificações restantes, resultando em código de máquina para processadores de propósito geral e em uma “rede de ligações” (netlist) para o processador de propósito único. Dentre os diversos modos de se otimizar o processo de projeto, destacam-se três: (a) compilação/síntese, (b) biblioteca/IP (Intellectual Property – Propriedade Intelectual) e (c) teste/verificação. 2.1.5.1 Compilação / Síntese Segundo Vahid e Givargis (2002, p. 17), a etapa de compilação/síntese permite ao projetista especificar a funcionalidade em uma forma mais abstrata, gerando os detalhes automaticamente, e pode ser aplicada aos diversos níveis de abstração. Alguns exemplos de síntese incluem: (a) síntese de sistema, que converte uma especificação do sistema em um programa seqüencial; (b) síntese comportamental, que transforma um programa seqüencial em máquinas de estados e operações de transferência entre registradores; (c) síntese RT, que transforma máquinas de estados e 3 Mutiplexadores, registradores, unidades funcionais e outros. 15 transferências entre registradores em controlador implementado por equações booleanas e um caminho de dados com componentes RT; e (d) síntese lógica, que converte expressões booleanas em interconexões de um conjunto de portas lógicas primitivas (REIS, 2002, p. 119; VAHID; GIVARGIS, 2002, p. 17). 2.1.5.2 Bibliotecas / IP Segundo Vahid e Givargis (2002, p.18), o uso de bibliotecas permite a re-usabilidade de implementações existentes, assim, melhorando a produtividade. Conforme apresentado pelos autores, bibliotecas ou IPs podem ser aplicados aos diversos níveis de abstração com os seguintes objetivos: (a) nível de sistema: disponibilizar sistemas completos para solução de problemas particulares ou apenas parte do sistema; (b) nível comportamental: disponibilizar componentes como multiplexadores, registradores e até processadores; (c) nível RT: disponibilizar layouts de componentes RTs; e (a) nível lógico: disponibilizar layouts de blocos lógicos. Houve uma mudança muito importante no conceito de bibliotecas. Ao invés disponibilizar componentes apenas na forma de CIs, passou-se disponibilizá-los também em forma do que é chamado de core ou IP. Segundo Gupta e Zorian (1997, p. 2), os cores podem ser disponibilizados nas seguintes formas: • Soft: consiste em uma descrição HDL(Hardware Description Languages); • Hard: consiste em layouts de blocos lógicos; e • Firm: consiste em um netlist de portas lógicas. Segundo Vahid e Givargis (2001), o projetista integra vários cores para construir um sistema. Os autores ressaltam que encontrar um core com a funcionalidade desejada pode ser considerada uma tarefa difícil. 2.1.5.3 Teste e Verificação Teste e verificação são processos que visam assegurar que: (a) a implementação de uma funcionalidade esteja correta; (b) determinadas situações simultâneas nunca ocorram; e (c) o sistema não ficará em algum laço infinito (VAHID; GIVARGIS, 2002, p. 18). Durante o desenvolvimento esses processos são feitos utilizando-se simuladores nos diversos níveis de 16 abstração. Após a implementação, são aplicados tanto nos protótipos, quanto nos produtos fabricados. 2.1.6 Linguagem de descrição de hardware e VHDL Uma linguagem de descrição de hardware (HDL – Hardware Description Languages) permite o projeto de circuitos lógicos digitais através de uma linguagem semelhante às linguagens de programação de alto nível. Com a HDL, é possível descrever detalhes do sistema lógico, como funções individuais, propriedade dos sinais e a conexão entre os blocos (UYEMURA, 2002, p. 127). Segundo Mendonça e Zelenovsky (2004, p. 469), existem diversas linguagens com este propósito, entre elas: (a) Verilog; (b) AHDL (Altera HDL); (c) ABEL (Advanced Boolean Expression Language); e (d) VHDL (VHSIC4 HDL). Dentre as linguagens de descrição de hardware mencionadas, em universidades brasileiras, a mais popular é a VHDL. Para Mendonça e Zelenovsky (2004, p. 470) o uso de VHDL em projetos apresenta as seguintes vantagens: 1. Portabilidade: Ferramentas de desenvolvimento para FPGA e a confecção de VLSI utilizam VHDL; 2. Flexibilidade: Alterações no projeto podem ser facilmente realizadas com alterações no código fonte; e 3. Interface de alto nível com a eletrônica: O uso da linguagem VHDL abstrai informações do nível de eletrônica, pois a linguagem VHDL não está em contato direto com elementos da eletrônica digital, como flip-flops e contadores. Segundo D’Amore (2005, p. 1) e Mendonça e Zelenovsky (2004, p. 469), a linguagem VHDL é resultado de um projeto patrocinado pelo Departamento de Defesa dos Estados Unidos da América com empresas como IBM, Texas Instruments e Intermetrics. Conforme D’Amore (2005, p. 1), a linguagem foi concebida com a finalidade de documentar padrões de projeto. Por isso, algumas instruções presentes na linguagem não são sintetizáveis em hardware, porém essas instruções são utilizadas para a simulação de projetos. 4 Abreviação dada pelo Departamento de Defesa dos Estados Unidos para um projeto chamado Very High-Speed Integrated Circuits. 17 2.2 Arquitetura e Organização de Computadores O desenvolvimento e o estudo do processador envolvem conceitos da arquitetura e da organização do mesmo. O estudo da arquitetura do computador refere-se principalmente à parte do computador visível ao programador como: (a) o conjunto de instruções; (b) os modos de endereçamento; (c) a memória de programa e dados; (d) os registradores; (e) as portas de entrada/saída; e (f) as interrupções. Já o estudo da organização, também conhecida como microarquitetura de processadores (CARTER, 2003, p. 87-89), trata de aspectos não visíveis ao programador, ou seja, trata de como o processador é implementado, abordando blocos básicos como (i) caminho de dados e (ii) unidade de controle. Nesse contexto, o objetivo desta seção é apresentar os conceitos básicos e necessários sobre arquitetura e organização de computadores para o presente projeto. 2.2.1 Arquitetura 2.2.1.1 Conjunto de Instruções Para o processador uma instrução é um arranjo de bits que indica uma seqüência de micro- operações que deverá ser executada. As instruções podem ser classificadas de acordo com o seu propósito e formato como (a) instruções de transferência de dados5 (também denominadas de carga e de armazenamento); (b) instruções lógicas6 e aritméticas7; (c) instruções de teste (ou de comparação); e instruções de desvio (condicional ou incondicional). As denominações dessas classes variam de autor para autor. O conjunto de todas as instruções reconhecidas por um computador é chamado de conjunto de instruções (WEBER, 2004, p. 35-36) Em linguagem de montagem, a instrução é representada por um identificador (o código da operação ou opcode) e normalmente seguido por um ou mais operandos. Na instrução, o operando pode ser um valor, um endereço de um registrador ou um endereço para uma posição na memória de programa (utilizado nas instruções de desvio). Essas variações de posição e quantidade de operandos são denominadas de modos de endereçamento, ou seja, que podem ser definidos como um conjunto de sintaxe que especificam constantes, registradores e posições de memória (CARTER, 2003, p. 82; HENNESSY; PATTERSON, 2003, p. 72; WEBER, 2004, p. 35-36). 5 Instruções para copiar dados entre memória, entre registradores e entre registradores e memórias. Instruções de lógica E, OU e outras, além de instruções de deslocamento de bits 7 Instruções de soma e de subtração. 6 18 Segundo Hennessy e Patterson (2003, p. 67-68), a forma do armazenamento interno do processador influencia no conjunto de instruções, já que os operandos das instruções variam de acordo com o tipo de armazenamento. Assim, têm-se os seguintes tipos de arquitetura: • Arquitetura de pilha: Armazenamento baseado em pilha. Os operandos estão implicitamente no topo da pilha. Conforme a Figura 5 (a), a arquitetura possui um registrador TOS (Top of Stack) que armazena o topo da pilha. Os dois operandos são retirados do topo da pilha, processados e o resultado armazenado no topo da pilha; • Arquitetura de acumulador: Armazenamento baseado em um registrador chamado de acumulador. Um dos operandos de uma instrução é implicitamente o acumulador. Conforme a Figura 5 (b), após o cálculo na ULA, o resultado é armazenado no acumulador e assim o acumulador é um operando de entrada e de resultado; e • Arquitetura de registradores de uso real: Armazenamento baseado em banco de registradores. Os operandos são explícitos como registradores ou posições de memória. Duas alternativas são ilustradas na Figura 5: (i) um dos operandos fonte da ULA pode ser uma variável armazenada na memória – Figura 5 (c); e (ii) apenas registradores podem servir de operandos fonte para a ULA, sendo que as variáveis são carregadas e atualizadas por meio de instruções de transferência (load-store) – Figura 5 (d). Figura 5. Fonte dos operando nas diferentes classes de conjunto de instruções. Fonte: Adaptado de Hennessy e Patterson (2003, p. 68) 19 Na Figura 5, as setas indicam se um operando é uma entrada e/ou saída da ULA. Os sombreados claros representam entradas, e os escuros resultados. A forma mais comum de se classificar os computadores em relação ao conjunto de instruções é quanto à quantidade e tipo de instrução suportada. Duas classes são utilizadas: máquinas CISC (Complex Instruction Set Computers) e máquinas RISC (Reduced Instruction Set Computer) (ver Seção 2.2.1.2). Segundo Carter (2003, p.81), a arquitetura do conjunto de instruções segue perdendo significância dentro do projeto de processadores por dois motivos: (i) a programação é normalmente realizada em uma linguagem de alto nível e toda a codificação para a linguagem de máquina é realizada por compiladores; e (ii) os consumidores esperam compatibilidade entre as versões de um mesmo processador. Logo, o lançamento de um novo processador deverá conter, no mínimo, as mesmas instruções da versão anterior. Já para Stallings (2002, p. 347), o projeto do conjunto de instruções é um ponto fundamental e mais analisado dentro do projeto de computadores, pois este determina vários aspectos sobre sua organização. 2.2.1.2 CISC e RISC Durante a década de 70, uma tendência impulsionada pelo avanço da tecnologia de hardware foi a aproximação da linguagem de máquina a uma linguagem alto nível com o incremento de instruções, modos de endereçamento, registradores e outros visando o aumento do desempenho, já que o número de instruções de máquina necessário para implementar um programa seria menor. Essa tendência resultou em máquinas denominadas máquinas CISC, as quais continham um conjunto de instruções bastante diversificado. Porém com a evolução dos compiladores, começou a ser questionado o desempenho das máquinas CISC, o que levou ao desenvolvimento das máquinas com um conjunto de instruções reduzido, RISC. (CARTER, 2003, p. 81; STALLINGS, 2002, p. 519-520; UYEMURA, 2002, p. 383). Patterson e Hennessy (2000) apresentam o resultado de um teste com um conjunto de aplicações em processador CISC Intel® 80x86 na qual resultou em que 10 instruções simples8 (freqüentemente encontradas em arquiteturas RISC) eram responsáveis por 96% das instruções 8 load, conditional branch, compare, store, add, and, sub, move register-register, call, return 20 executadas, reforçando a idéia da máquina RISC, ou seja, máquina com hardware mínimo para implementar as instruções mais freqüentes com desempenho esperado. Apesar da controvérsia em determinar qual das duas opções era a melhor, houve uma convergência entre as duas máquinas da seguinte forma: (i) máquinas RISC agregaram algumas instruções complexas das máquinas CISC; e (ii) máquinas CISC excluíram do seu conjunto instruções complexas que não eram utilizadas com freqüência (CARTER, 2003, p. 81; STALLINGS, 2002, p. 520). Segundo Carter (2003, p.81-82), uma diferença clara entre as duas é que máquinas RISC são arquiteturas de load-store – Figura 5 (c), já em máquinas CISC, instruções como, por exemplo, aritméticas, podem ler ou gravar seu resultado diretamente na memória – Figura 5 (d). 2.2.1.3 Registradores Em um processador existem diversos registradores, sendo que vários destes devem ser de conhecimento do programador, denominados de registradores especiais. Weber (2004, p. 34-35) relaciona alguns dos registradores especiais comumente encontrados em arquiteturas de computadores como: • Apontador de Instrução: normalmente referenciado como PC (Program Counter), este registrador contém o endereço da próxima instrução a ser executada; 2.2.1.4 • Registrador de Instrução (RI): armazena a instrução que está sendo executada; e • Registrador de Estado (STATUS): armazena informações sobre os resultados da ULA. Portas de Entrada/Saída As portas de Entrada/Saída (E/S) são os meios físicos que permitem o processador se comunicar com o mundo externo, seja para trocar informações com o usuário do sistema, seja para acessar outros dispositivos. Uma classe de dispositivos normalmente associados a portas de entrada/saída são dispositivos de armazenamento (por exemplo, memórias e disco rígido). Embora muitas vezes ignorada, a entrada/saída influencia o desempenho do sistema (CARTER, 2003, p. 201-202; PATTERSON; HENNESSY, 2000, p. 375; WEBER, 2004, p. 249-254). 21 2.2.1.5 Interrupções Interrupção é o mecanismo oferecido pelo processador para: (a) permitir que dispositivos externos interrompam o programa atual do processador para atender sua necessidade; (b) evitar que o processador tenha que pesquisar todos os dispositivos verificando se algum necessita de atendimento, este procedimento é conhecido como polling; e (c) permitir que o processador execute operações de outro programa enquanto o programa atual aguarda por uma resposta de um dispositivo assíncrono, e volte a processar o mesmo programa quando o dispositivo ativa a interrupção informando que já concluiu a tarefa. (CARTER, 2003, p. 204-206; MENDONÇA; ZELENOVSKY, 2004, p. 449-451; WEBER, 2004, p. 253). 2.2.2 Organização 2.2.2.1 Caminho de Dados O caminho de dados é formado pela unidade de execução e pelo banco de registradores, ou seja, o hardware necessário para a execução de uma instrução. A unidade de execução é composta por uma ou mais ULAs, registradores de uso geral e específico (ver Subseção 2.2.1.3), além de um barramento interligando esses componentes. A execução de uma instrução na unidade de execução segue um ciclo chamado de ciclo de instrução, que é normalmente composto por uma variação das seguintes etapas (CARTER, 2003, p. 87-88; PATTERSON; HENNESSY, 2000, p. 200-204; WEBER, 2004, p. 36): • Busca de Instrução: O registrador de instrução (RI) recebe a instrução da memória de instrução apontada pelo registrador PC. O registrador PC é atualizado para o endereço da próxima instrução; • Decodificação da Instrução: Nesta etapa, a instrução armazenada no registrador RI é decodificada pela unidade de controle a fim de definir quais operações serão realizadas nas etapas posteriores; • Leitura dos Registradores: Os operandos envolvidos na instrução, identificados na etapa anterior, são carregados do banco de registradores; • Execução: Nesta etapa, é realizado o cálculo na ULA de acordo com a operação identificada na etapa de decodificação; e 22 • Escrita: O resultado da operação da ULA é armazenado no banco de registradores. Segundo Patterson e Hennessy (2000, p. 200), banco de registradores é conjunto de registradores com propriedade de leitura e escrita. O acesso a registradores é mais rápido que em memórias, além de permitir acesso simultâneo aos registradores. Os processadores que possuem instruções de ponto flutuante normalmente implementam um banco de registrador para tratar esse tipo de dado e outro para dados tipo inteiro. O mesmo acontece com a ULA. (CARTER, 2003, p. 87-88; WEBER, 2004, p. 36). 2.2.2.2 Unidade de Controle A unidade de controle é responsável por gerenciar o caminho de dados, memórias e dispositivos de E/S de acordo com a instrução armazenada no registrador de instrução (IR). Para tal, existem vários sinais de controles ligando os componentes do processador a um componente com a lógica de controle. Cada sinal de controle gerencia uma microoperação como, por exemplo, seleção de uma operação da ULA e ativação da memória (MENDONÇA; ZELENOVSKY, 2004, p. 412; WEBER, 2004, p. 33-34). Shiva (2000) considera a unidade de controle o bloco mais complexo do hardware do processador no ponto de vista do projetista, pois este bloco deve gerar sinais de controle para todos os outros blocos determinando a ação de cada bloco conforme a instrução atual. Segundo Weber (2004, p. 34), as unidades de controle são máquinas de estados finitos (Finite State Machine - FSM) obtidas por lógica seqüencial9 e podem ser implementadas de várias formas. Usualmente as implementações se caracterizam como: (i) Organização convencional, onde a unidade de controle é composta de diversos componentes digitais que geram os sinais de controles seqüencialmente e no tempo adequado para cada bloco; e (ii) Organização microprogramada, na qual os sinais de controles são armazenados em uma pequena memória reservada para este fim, chamada memória de controle. 2.2.2.3 Memórias O sistema de memória serve como um local para armazenamento de dados e programa. A memória é dividida em “palavras”, na qual cada uma é identificada por um endereço. Existem dois tipos básicos de memória: (i) ROM (Read Only Memory – Memória Apenas de Leitura), que 9 A saída é resultado dos sinais de entrada e do valor armazenado internamente. 23 permite acesso apenas para leitura dos dados e nos computadores em geral é utilizada para armazenar o programa de inicialização; e (ii) RAM (Random Access Memory – Memória de Acesso Aleatório), que permite tanto a escrita quanto a leitura de dados e é utilizada para armazenar programas, sistemas operacionais e dados (CARTER, 2003, p. 50-51; WEBER, 2004, p. 31-32). Os computadores também se diferenciam quanto à organização da memória de dados e da memória de instruções, podendo estas estarem juntas em um mesmo espaço de endereçamento ou separadas. Quando a memória de dados utiliza um espaço diferente da memória de instrução é referenciado como arquitetura de Harvard (Figura 6 (a)). Quando as memórias utilizam o mesmo espaço de memória é referenciado como arquitetura de Princeton (ou de von Neumann) conforme Figura 6 (b). A arquitetura de Princeton pode resultar em hardware mais simples, porém a arquitetura de Harvard pode resultar em um desempenho melhor, já que pode haver acesso simultâneo nas duas memórias. (PREDKO, 1998, p. 8) Processador Processador Memória Dados Memória (Dados e Programa) Memória Programa (a) Arquitetura Harvard (b) Arquitetura Princeton Figura 6. Arquitetura de Memória Fonte: Adaptado de Vahid e Givargis (2002) Outro aspecto importante no sistema de memória refere-se à hierarquia de memória. Existem vários níveis de hierarquia de memória composta principalmente de memória cache, memória principal e memória secundária. Como mostra a Figura 7, quanto mais próxima do processador, a memória possui (a) um melhor desempenho; (b) menor tamanho; e (c) maior custo (HENNESSY; PATTERSON, 2003, p. 284; PATTERSON; HENNESSY, 2000, p. 318-319). 24 Figura 7. Métricas da hierarquia de memória Fonte: Adaptado de Hennessy e Patterson (2003, p. 284); Patterson e Hennessy (2000, p. 319) 2.3 Processador BIP II A família de processadores BIP (Basic Instruction-set Processor) foi desenvolvida por pesquisadores do Laboratório de Sistemas Embarcados e Distribuídos – LSED do Curso de Ciência da Computação da Universidade do Vale do Itajaí – UNIVALI com o objetivo de estabelecer uma arquitetura de processador simplificada com recursos incrementais que favoreça o ensino de Arquitetura e Organização de Computadores para alunos de séries iniciais do curso de Computação, no intuito de relacionar os conteúdos de programação com as suas representações em hardware como: (a) declaração de variável e alocação de memória; (b) constantes e operandos imediatos; (c) atribuição de variáveis e operações de acesso a memória; e (d) operações aritméticas e a execução no hardware. (MORANDI et al., 2006). Conforme Morandi et al (2006), no desenvolvimento do BIP, foram estabelecidas três diretrizes de projeto: • A arquitetura deveria ser simples o suficiente para facilitar o entendimento de seu funcionamento e a sua implementação em disciplinas de circuitos digitais; • A arquitetura deveria ser extensível; e • Todas as ferramentas de apoio desenvolvidas deveriam priorizar o uso de estrutura de linguagens compreendida por alunos de séries iniciais. Baseado nestas diretrizes foram definidos dois modelos iniciais de processador (MORANDI; RAABE; ZEFERINO, 2006): 25 • BIP I: com foco no suporte ao entendimento de conceitos como níveis de linguagem, constantes, variáveis, representação de dados e de instruções, conjuntos de instruções, programação em linguagem de montagem e geração de código na linguagem da máquina; e • BIP II: uma extensão do BIP I, com foco na inclusão de suporte aos conceitos de estruturas de controle para desvios (condicionais e incondicionais) e laços de repetição. Como o BIP II é uma extensão do BIP I, as subseções a seguir apresentam características da versão mais completa. 2.3.1 Arquitetura do BIP II Segundo Morandi et al (2006), o BIP II possui uma arquitetura RISC baseada nos microcontroladores PIC® (Programmable Intelligent Computer) da Microchip®. Ela é uma arquitetura baseada em acumulador, semelhante àquela apresentada previamente na Figura 5 (b), em que todas as operações envolvem o acumulador e algumas operações utilizam operandos da memória. Segundo os autores, essa duas especialidades do BIP II descaracterizam-no como uma máquina RISC pura. Porém, outras características RISC prevalecem como a regularidade das instruções, o número reduzido de instruções, modos de endereçamento e formatos de instrução. Conforme mostra a Tabela 1, o formato de instrução está divido em dois campos: 5 bits para o código da operação, o que permite a implementação de até 32 instruções; e 11 bits para o operando, o que permite representar endereços em uma faixa de até 2048 posições, ou constantes com sinal em uma faixa de valores de -1024 a 1023. Uma das mudanças realizadas na extensão do BIP I para o BIP II foi a inclusão da classe de instruções de desvio visando a implementação de desvios condicionais, incondicionais e laços de repetição. 26 Tabela 1. Arquitetura do BIP II Tamanho da palavra de dados Tipos de dados Tamanho da palavra de instrução Formato de instrução Modos de endereçamento Registradores Classes de instrução 16 bits Inteiro de 16 bits com sinal –32768 a +32767 16 bits 15 14 13 12 11 10 Cód. Operação 9 8 7 6 5 4 Operando 3 2 1 0 Direto: o operando é um endereço da memória Imediato: o operando é uma constante ACC: acumulador PC: contador de programa STATUS: registrador de Status IR: registrador de instruções (depende da implementação) Armazenamento: STO Carga: LD e LDI Aritmética: ADD, ADDI, SUB e SUBI Controle: HLT Desvio: BEQ, BNE, BGT, BGE, BLT, BLE e JMP Fonte: Adaptado de Morandi, Raabe e Zeferino (2006) Com relação aos registradores, o BIP II possui de três a quatro: PC, ACC, STATUS e IR. O registrador STATUS possui dois flags: (i) Z, que indica se o resultado da última operação da ULA foi igual a zero ou não; e (ii) N, que indica se o último resultado da ULA foi um número negativo ou não (MORANDI et al, 2006). Dependendo da implementação do processador, ele pode incluir ou não um registrador para armazenar a instrução em execução (IR – Instruction Register). Na sua implementação mais simples (organização monociclo), esse registrador não é utilizado. A Tabela 2 apresenta o conjunto de instruções do processador BIP II. Na tabela, é possível observar as alterações nos registradores ACC (terceira coluna) e PC (quarta coluna) em cada instrução. Na tabela, o termo Memory[operand] representa uma variável alocada em memória na posição operand. 27 Tabela 2. Conjunto de instruções do BIP II Opcode 00000 00001 00010 00011 00100 00101 00110 00111 Instrução HLT STO LD LDI ADD ADDI SUB SUBI operand operand operand operand operand operand operand 01000 BEQ operand 01001 BNE operand 01010 BGT operand 01011 BGE operand 01100 BLT operand 01101 BLE operand 01110 0111111111 JMP operand Operação e atualização do PC Desabilita atualização do PC PC ← PC Memory[operand] ← ACC ACC ← Memory[operand] ACC ← operand ACC ← ACC + Memory[operand] ACC ← ACC + operand ACC ← ACC – Memory[operand] ACC ← ACC – operand PC PC PC PC PC PC PC ← ← ← ← ← ← ← PC PC PC PC PC PC PC + + + + + + + 1 1 1 1 1 1 1 Se (STATUS.Z=1) então PC ← endereço Senão PC ← PC + 1 Se (STATUS.Z=0) então PC ← endereço Senão PC ← PC + 1 Se (STATUS.Z=0) e (STATUS.N=0) então PC ← endereço Senão PC ← PC + 1 Se (STATUS.N=0) então PC ← endereço Senão PC ← PC + 1 Se (STATUS.N=1) então PC ← endereço Senão PC ← PC + 1 Se (STATUS.Z=1) ou (STATUS.N=1) então PC ← endereço Senão PC ← PC + 1 PC ← endereço Reservado para as futuras gerações Fonte: Adaptado de Zeferino (2007) 28 2.3.2 Organização do BIP II Segundo Morandi et al (2006), a organização utiliza a estrutura Harvard, com memórias separadas para dados e instruções, como mostra a Figura 8. Conforme a figura, o processador é dividido em dois blocos: (i) Controle, responsável por gerar sinais de controle para o caminho de dados e atualização do PC; e (ii) Caminho de Dados, que inclui os circuitos necessários para executar a instrução. CPU Control Datapath Extensão de Sinal 1 Decoder + 1 ena 0 Opcode 2 SelA Branch WrPC SelA SelB WrAcc Op WrRam N Z WrAcc ena 1 0 ACC Op PC 1 0 SelB +/– Operand Z N Instruction Addr Data Wr Addr Program Memory In_Data Data Memory Figura 8. Organização do Processador BIP II Fonte: Adaptado de Zeferino (2007) 29 Out_Data A Tabela 3 apresenta a tabela-verdade de especificação do decodificador de instruções. Conforme pode ser observado, apenas a instrução HLT não atualiza o PC e os valores de Z e N só são relevantes nas instruções de desvio. Tabela 3. Tabela de decodificação de instrução Mnemônico HLT STO LD LDI ADD ADDI SUB SUBI BEQ BNE BGT BGE BLT BLE JMP Reservado Entradas Opcode Z X 00000 X 00001 X 00010 X 00011 X 00100 X 00101 X 00110 X 00111 1 01000 0 01001 0 01010 X 01011 0 01100 0 01101 0 1 1 X Saídas N Op SelA SelB WrACC WrRAM WrPC Branch X X X X X X X X X X 0 0 1 0 1 0 1 X 01110 01111-11111 X X X X X X 0 0 1 1 X X X X X X X X X X XX XX 00 01 10 10 10 10 XX XX XX XX XX XX XX XX XX XX X X X X 0 1 0 1 X X X X X X X X X X 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 X 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 X X X 0 0 0 X Fonte: Zeferino (2007) 30 2.4 Microcontroladores Para Marinho e Marinho (2001) e Predko (1998), microcontroladores são sistemas computacionais composto de processador, memórias; entradas e saídas e vários outros componentes (temporizador, interface de comunicação serial, conversores analógico/digital, e outros), que em sistemas computacionais tradicionais são independentes, e em microcontroladores são integrados em um único chip. Predko (1998, p. 4) classifica os diferentes tipos de microcontroladores em três grupos: • Microcontroladores Embarcados: nessa classe de microcontrolador, todos os recursos necessários estão disponíveis no chip, precisando apenas de energia e do sinal de relógio (clock). Outras características dessa classe incluem: baixo custo, uso de uma lógica de controle programável e disponibilidade de interface para dispositivos externos. O caminho de dados normalmente possui 8 bits e a freqüência de operação é inferior a 10MHz; • Microcontroladores com memória externa: essa classe é composta por microcontroladores que dependem completamente de memória externa (memória de programa e memória RAM). Esses microcontroladores são utilizados em aplicações como cache/buffer de discos rígidos e distribuidores de grande quantidade de dados; e • Processadores de Sinal Digital (DSP – Digital Signal Processor): possuem as características de um processador de aplicação específica apresentado na Seção 2.1.3.3. 2.4.1 Características de Microcontroladores As subseções a seguir têm a finalidade de explorar e conhecer os componentes internos e características normalmente encontradas em um microcontrolador. 2.4.1.1 Processador Segundo Marinho e Marinho (2001), os microcontroladores possuem internamente uma CPU interligada com os outros blocos do microcontrolador, que tem a responsabilidade de gerenciar os blocos restantes bem como executar as instruções do programa. Uma métrica de 31 microcontrolador relacionada ao processador é a freqüência máxima de operação, normalmente medida em MHz (Megahertz) e a presença ou não de um oscilador10 interno. 2.4.1.2 Memórias A memória é um recurso indispensável para o funcionamento do microcontrolador. Marinho e Marinho (2001) apresentam alguns dos tipos mais comuns de memórias em microcontroladores disponíveis no mercado: • RAM (Random Access Memory): memória volátil11 com acesso aleatório e com propriedade de leitura e escrita. Normalmente utilizada para armazenar dados e variáveis; • ROM (Read Only Memory): memória não volátil apenas de leitura cujo conteúdo é configurado no momento da fabricação do chip. É Utilizada para armazenar o programa do microcontrolador; • PROM (Programmable ROM): memória apenas de leitura que pode ser configurada após a sua fabricação, mas apenas uma única vez; • EPROM (Erasable PROM): memória apenas de leitura que é gravada por um dispositivo específico e apagada por raio ultravioleta diversas vezes; • EEPROM (Electrically EPROM): similar à memória EPROM, porém é apagada eletricamente; e • Memória Flash: memória não volátil com boa relação custo/benefício e pode ser gravada quando aplicado uma tensão elétrica de 5 ou 12 volts, dependendo do microcontrolador. É muito similar à memória EEPROM, porém permite apagar um “bloco” de conteúdo, já nas EEPROM é realizado bit a bit. Predko (1998, p. 11) classifica as memórias em três grupos: • Memória de Programa: Memória não volátil (ROM, PROM, EPROM, EEPROM e Flash) que contém uma tabela de dados e o programa executado pelo microcontrolador; 10 11 Componente responsável por gerar os pulsos de clock ao microcontrolador constantemente em intervalos fixos. Dispositivo de memória cujo conteúdo se perde na ausência de tensão elétrica de alimentação. 32 • Área Variável: Memória volátil (RAM) que contêm variáveis e parâmetros temporários do sistema; e • Pilha (stack): Memória volátil (RAM) baseada na estrutura de dados LIFO (Last In First Out –Último a Entrar, Primeiro a Sair), utilizada, por exemplo, em chamada de subrotina pelo sistema. Outras características relevantes, e também métricas de microcontroladores ao tratar de memórias, referem-se à capacidade de armazenamento e o tamanho da palavra. A memória de dados normalmente possui uma capacidade muito inferior à memória de programa. 2.4.1.3 Portas de E/S Segundo Predko (1998, p. 16), para interagir com o mundo exterior, o microcontrolador utiliza-se de portas de E/S. Portas de E/S são registradores ligados a pinos do microcontrolador, e podem ser programadas para serem apenas entrada, apenas saídas ou ambos (bidirecional) (MATIC, 2000). Comumente, os microcontroladores oferecem recursos extras ligados a portas de E/S, como comunicação serial, comunicação paralela, conversor analógico/digital e outros. Deve-se destacar que a quantidade de portas e os recursos ligados a estas são algumas das métricas de microcontroladores referente a portas de E/S. 2.4.1.4 Comunicação Serial Conforme Matic (2000) e Marinho e Marinho (2001), a comunicação serial é maneira de economizar a quantidade de portas de E/S necessárias para transmitir dados, além de favorecer transmissões de longa distância. A comunicação visa o envio e recebimento de dados bit-a-bit em série. Segundo os autores, a comunicação serial deve obedecer a um conjunto de regras que definem como será realizada a transmissão e a receptação dos dados, este conjunto chama-se protocolo. Os protocolos mais comuns são o I2C(Inter-Integrated Circuit) e SPI (Serial Peripheral Interface). Segundo Marinho e Marinho (2001), para realizar a comunicação existem três tipos de sistemas de interligação digitais: • simplex: existe apenas uma porta de comunicação e funciona de forma unilateral, na qual um transmite e outro recebe, Figura 9 (a); 33 • half-duplex: possui dois caminhos de comunicação, um para envio e outro para recebimento, porém não há transmissão e recebimento simultâneos, Figura 9 (b); e • full-duplex: igual ao half-duplex, porém permite enviar e receber dados simultaneamente, Figura 9 (c). Figura 9. Sistemas de Interligação Digitais. TX (Transmissor) e RX (Receptor) Fonte: Marinho e Marinho (2001) 2.4.1.5 Temporizador Segundo Matic (2000) e Souza e Noveletto (2007) o temporizador (timer) é muito importante dentro do contexto de microcontroladores e requer uma atenção especial. Ele é composto basicamente por um contador, cujo valor é incrementado em intervalos fixos e podendo gerar uma interrupção no estouro12 desse contador. Conforme Souza (2004) o sistema de temporização normalmente disponibiliza um função denominada prescaler que permite configurar a quantidade pulsos de clock necessários para incrementar o contador do timer. Segundo Souza e Noveletto (2007), através desta unidade é possível realizar medição de tempo e freqüência e gerar pulsos. Como métricas de microcontroladores destacam-se a quantidade de temporizadores e a quantidade de bits de cada contador. 2.4.1.6 Sistema de Rearme Automático (Watchdog) Muitos dos sistemas microcontrolados encontram-se em lugares isolados ou de difícil acesso, como no interior de um equipamento, e muitas vezes impossibilitando que o usuário reinicie o microcontrolador na ocorrência de algum erro de software ou hardware. Para evitar esse problema, os microcontroladores geralmente incluem um tipo especial de temporizador denominado 12 Quando se ultrapassa o valor máximo suportado por um registrador. 34 watchdog. Quando o contador desse temporizador estoura o seu limite de contagem, ele provoca a reinicialização do microcontrolador. 2.4.1.7 Interrupções Conforme já apresentado em seções anteriores e apresentado por Marinho; Marinho (2001), interrupção é o mecanismo que permite interromper um programa para a execução de uma rotina com a função desejada relacionada à fonte de interrupção. Em microcontroladores, as interrupções estão presentes, por exemplo, nas portas de E/S (com interrupção ativada na mudança de estado da porta), na unidade de temporização (é gerada uma interrupção sempre que o contador alcança um determinado valor) e na interface de comunicação serial (é gerada uma interrupção quando um dado é recebido). Segundo Marinho e Marinho (2001), quando duas ou mais interrupções são ativas no mesmo instante de tempo, é atendida pelo processador a interrupção que tiver maior prioridade. Algumas interrupções podem ser habilitadas ou desabilitadas via software, configurando-se bits em um registrador. Como métricas de microcontroladores, deve-se levar em conta a quantidade e as fontes de interrupções do microcontrolador. 2.4.1.8 Conversores Analógico-Digital e Digital-Analógico Os sinais elétricos manipulados pelos microcontroladores são sinais digitais. Porém, muitos periféricos utilizam sinais analógicos incompreendidos pelos microcontroladores. Segundo Matic (2000) e Souza e Noveletto (2007), o conversor Analógico-Digital (conversor A/D) transforma dados analógicos em dados digitais, ou seja, bits. Esse conversor possui uma propriedade denominado precisão que é medida em bits, na qual, quanto maior o número de bits de um conversor, maior será sua precisão e vice-versa. Assim, alguns exemplos de conversores A/D são A/D de 8 bits, A/D de 10 bits, A/D de 12 bits e assim por diante. A função do conversor DigitalAnalógico é justamente o contrário. A precisão e a quantidade de portas de E/S com suporte a esses conversores podem ser consideradas métricas de microcontroladores. 35 2.4.1.9 Comparadores Analógicos Comparador Analógico é um recurso que permite realizar a comparação entre duas tensões de entrada no microcontrolador. Segundo Souza e Noveletto (2007), este recurso permite detectar a ocorrência de um curto-circuito na aplicação, realizar a conversão analógico-digital com auxílio de hardware auxiliar, efetuar a detecção de limiar de mudança de nível, entre outras. Como métrica de microcontroladores, tem-se a quantidade de comparadores disponível. 2.4.1.10 PWM Segundo Souza e Noveletto (2007) e Souza (2004), o recurso de PWM (Pulse Width Modulator) permite gerar uma seqüência de pulsos com largura variável, regulados por um filtro passa-baixa que tem como resultado a tensão proporcional ao duty cycle dessa seqüência. Como métricas de microcontroladores pode-se destacar a precisão em bits de tal recurso e a quantidade de comparadores disponível. 2.4.1.11 Modo Sleep Também conhecido como modo de baixo consumo, o modo Sleep é um recurso disponibilizado pelo microcontrolador e acionado por software que paralisa o oscilador e conseqüentemente o processamento, até que um evento especial ocorra fazendo que o microcontrolador volte à atividade. Esse recurso é fundamental para aplicações alimentadas por pilhas e baterias, já que no tempo em que o microcontrolador está em modo sleep, o consumo de energia é menor (SOUZA, 2004, p. 162; SOUZA; NOVELETTO,2007). 2.4.1.12 Microcontroladores Comerciais O objetivo desta subseção é apresentar um estudo comparativo de alguns modelos de microcontroladores comerciais, com foco naqueles mais utilizados no LSED13, laboratório ao qual este trabalho está vinculado. Esse estudo visa levantar as características presentes em cada microcontrolador: Conforme a Tabela 4, as colunas apresentam os modelos de microcontroladores comerciais, e as linhas apresentam as características desses microcontroladores. 13 Laboratório de Sistemas Embarcados e Distribuídos da UNIVALI (Universidade do Vale do Itajaí) 36 Tabela 4. Características de Microcontroladores comerciais Modelo Fabricante Freqüência Max. de Operação (MHz) Palavra de Dados (bits) Palavra de Instrução (bits) Memória de Dados RAM (bytes) Memória de Dados EEPROM (bytes) Memória de Instrução (palavra) I/O Ports (Qtd) Comunicação Serial Timers (Qtd) Watchdog PWM (Qtd) Interrupções (Qtd) Conversor A/D (Qtd/Bits) Comparador (Qtd) Pinos (Qtd) / Encapsulamento Conjunto de Instruções (Qtd) Arquitetura Interna PIC 16F628 Microchip ® 20 8 14 224 128 FLASH 2K 16 USART 2/8-bit 1/16-bit Sim 1/10-bit 10 0 2 18-pin DIP,SOIC 20-pin SSOP PIC 16F877 Microchip ® 20 8 14 368 256 FLASH 8K 33 MSSP USART 2/8-bit 1/16-bit Sim 1/10-bit 14 8/10-bit 0 40-pin DIP/SOIC 44-PLCC/QTF 35 Harvard RISC 35 Harvard RISC PIC 18F452 Microchip ® 40 8 16 1536 256 FLASH 16384 33 MSSP, USART 1/8-bits 2/16-bits Sim Max. 10-bit 18 8/10-bit 0 40-pin DIP 44-pin PLCC 44-pin TQFP 75 Harvard RISC 8051 Intel ® 12 8 Variável (8, 16) 128 + Até 64K externa ROM 4K + até 64K externa 32 UART Rabbit 3000 Rabbit Semiconductor ® 54 8 20 Externa Externa Externa 2/16-bit 10/8-bit 1/16-bit Sim 4/10-bit 16 0 0 128-pin LQFP/TFBGA Sim 0 5 0 0 40-pin DIP 44-pin PLCC 111 Von Neumann CISC 56 UART, HDLC 258 Von Neumann CISC MC68HC908QY4 Motorola ® 32 8 16 128 FLASH 4K 13 2/16-bit Sim 2/8-bit 6 4/8-bit 0 16-pin DIP/ SOIC/SSOP 262 Von Neumann CISC Fonte: Adaptado de Freescale (2004); Intel (1991); Microchip (2001); Microchip (2002); Microchip (2003); Rabbit Semiconductor (2007) Os microcontroladores listados na Tabela 4 possuem características bastante homogêneas, exceto pelo periférico comparador, presente em apenas um dos microcontroladores apresentados. Os periféricos Watchdog, Timer e Fontes de Interrupções estão presentes em todos os microcontroladores listados. Já os periféricos de Comunicação Serial e PWM só não estão presente em um dos microcontroladores. A freqüência das características apresentadas na Tabela 4 foi utilizada neste trabalho na elaboração de um Questionário (Apêndice B ) que será tratado mais adiante na Seção 3 . 2.5 ArchC O ArchC é uma Linguagem de Descrição de Arquitetura (Architecture Description Language, ADL) baseada no SystemC14, desenvolvido pelo Instituto de Computação da Universidade de Campinas (IC-UNICAMP) (THE ARCHC TEAM, 2007a). Segundo Baldassin (2005), uma ADL permite gerar automaticamente ferramentas de software (simulador, compilador, montador, ligador e depurador) com base em uma descrição da arquitetura de processador. Em sua versão atual (2.0), o ArchC permite descrever além da arquitetura, a hierarquia de memória do processador, gerando automaticamente ferramentas como simulador, montador, ligador e depurador. Segundo The ArchC Team (2007b), a descrição de uma arquitetura utilizando o ArchC é divida em dois blocos principais: (a) Recursos da Arquitetura (Architecture Resources - designada por AC_ARCH), a qual contém a descrição da quantidade e tipo de memória, da quantidade de registradores e do pipeline15; e (b) Arquitetura do Conjunto de Instruções (Instruction Set Architecture - designada por AC_ISA), a qual contém detalhes sobre o conjunto de instruções como: (i) formato; (ii) tamanho; (iii) identificador; (iv) decodificação; e (v) comportamento. As subseções a seguir apresentam mais informações sobre a descrição de uma arquitetura utilizando o ArchC, tomando como exemplo a descrição funcional do processador BIP-II (descrito 14 15 HDL baseada na linguagem de programação C/C++ Técnica de hardware que permite aumentar o desempenho do processador executando mais de uma instrução por vez. previamente na Seção 2.3)16. A solução completa dessa implementação pode ser encontrada no Apêndice A . Mais informações sobre como obter, instalar e utilizar os pacotes do ArchC e ferramentas auxiliares pode ser encontradas em The ArchC Team (2007a); The ArchC Team (2007b) e Apêndice D . 2.5.1 Recursos da Arquitetura (AC_ARCH) Para a geração das ferramentas de software através do ArchC é preciso informar dados referentes à sua arquitetura. Conforme The ArchC Team (2007b), o ArchC permite gerar ferramentas em diferentes níveis de detalhamento, como o modelo funcional, em que com pouca informação é possível gerar ferramentas que, por exemplo, analisem apenas o conjunto de instruções, ignorando aspectos de temporização ou pipeline, e o modelo com precisão de ciclos, no qual é possível construir ferramentas que considerem aspectos de temporização, pipeline e outras características estruturais que tornem o modelo mais realístico. 01. AC_ARCH(bip2){ 02. ac_mem memRAM:2K; 03. ac_mem memROM:64K; 04. ac_reg ACC; 05. ac_reg Z, N; 06. ac_wordsize 16; 07. 08. ARCH_CTOR(bip2) { 09. ac_isa("bip2_isa.ac"); 10. set_endian("big"); 11. }; 12. }; Figura 10. Descrição dos Recursos para o processador BIP-II A Figura 10 apresenta um exemplo de declaração dos recursos da arquitetura para o processador BIP-II em modelo funcional. Nesse exemplo, utilizou-se de algumas palavras-chaves da linguagem ArchC como: 16 O exemplo apresentado demonstra estudos já realizados nesta fase do TCC no sentido de se obter capacitação no uso do ArchC para a descrição do BIP, requisito para os trabalhos a serem desenvolvidos. 39 • AC_ARCH: inicia a declaração dos recursos da arquitetura seguida pelo nome do projeto entre parênteses; • ac_wordsize: declara o tamanho da palavra, no exemplo, 16 bits; • ac_mem: declara um dispositivo de armazenamento com capacidade em K(kilobyte), M(megabyte), G(gigabyte) ou byte quando não houver identificação. No exemplo, o dispositivo possui o nome de MEM e capacidade de 2 kilobyte; • ac_reg: declara um registrador, no exemplo, o registrador declarado é o ACC (acumulador); • ARCH_CTOR: indica o inicio do construtor do AC_ARCH, seguido pelo nome do projeto; • ac_isa: informa o nome do arquivo que possui a declaração do conjunto de instruções, AC_ISA. No exemplo, o arquivo é bip2_isa.ac; e • set_endian: informa o endianness17 da arquitetura, podendo ser big ou little, no exemplo, o BIP-II utiliza o big. O ArchC suporta diversas outras palavras-chaves, bem como suporte à hierarquia de memória. No entanto, está além do escopo do trabalho apresentar detalhes de tal linguagem. 2.5.2 Arquitetura do Conjunto de Instruções (AC_ISA) Conforme The ArchC Team (2007b), a arquitetura do conjunto de instruções é realizada através de dois arquivos: (i) arquivo contendo informações sobre o conjunto de instruções como formato, tamanho, as declarações, a seqüência de decodificação e o formato na linguagem assembly (utilizado para gerar o montador) – esse arquivo é escrito na própria linhagem ArchC; e (ii) arquivo contendo o comportamento das instruções – esse arquivo é escrito em C++/SystemC. 17 Refere-se à forma de ordenação dos bytes quanto à magnitude. No big-endian a ordenação do byte mais significativo para o menos significativo é feita da esquerda para direita, já no litte-endian da direita para esquerda (HENNESSY;PATTERSON,2003, P. 70). 40 2.5.2.1 Descrição do ISA Como mencionado, em um arquivo com extensão “.ac” são definidos dados referentes à arquitetura do conjunto de instrução (ISA). Esse arquivo deve conter dados referentes ao formato de instrução, conjunto de instruções, opcode, formatos de representação da instrução na linguagem de montagem, entre outros. Assim como o arquivo de Recursos da Arquitetura, este arquivo também é escrito em linguagem ArchC. A Figura 11 apresenta parte da descrição do conjunto de instruções do processador BIP-II. Essa descrição apresenta algumas palavras-chaves que são relacionadas abaixo (THE ARCHC TEAM, 2007b): • AC_ISA: indica o início de uma descrição de conjunto de instruções seguido pelo nome do projeto entre parênteses; • ac_format: declara o formato de uma instrução. A definição do formato inicia-se com a palavra-chave ac_format seguido pelo nome do formato (ex: Type_I) e os campos que compõem o formato. No exemplo, o formato Type_I possui dois campos “op” com 5 bits e “operand” com 11. Assim, a declaração de um campo segue o formato: %campo:Numero_Bits; • ac_instr <fmt>: utilizado para declarar uma ou mais instruções baseadas em um mesmo formato . A declaração inicia com a palavra-chave ac_instr, seguida pelo formato de instrução declarado previamente e por uma ou mais instruções (separadas por vírgulas). No exemplo, todas as instruções são baseadas no mesmo formato, mas são declaradas em linhas diferentes para organizá-las em função da classe a que pertencem (aritméticas, carga e armazenamento, controle, desvio condicional e desvio incondicional); • ISA_CTOR: indica o inicio da declaração do construtor; • set_asm: define uma declaração assembly para a instrução. Entre aspas duplas, deve conter os campos na linguagem assembly seguido pelos campos declarados no formato, por exemplo, na linha 10, a sintaxe set_asm(“hlt %imm”, operand) informa que o imediato (%imm) apresentado na sintaxe é referente ao campo “operand” definido no formato da instrução; e 41 • set_decoder: determina a seqüência de decodificação de uma instrução. No exemplo (linha 11), o set_decoder é utilizado para atribuir o valor do opcode da instrução ao campo “op”, definido no formato da instrução. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. AC_ISA(bip2){ ac_format Type_I ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> = "%op:5 %operand:11"; add, sub, addi, subi; sto,ld,ldi; hlt; beq, bne, bgt, bge, blt, ble; jmp; ISA_CTOR(bip2){ hlt.set_asm("hlt %imm", operand); hlt.set_decoder(op=0x00); sto.set_asm("sto %imm", operand); sto.set_decoder(op=0x01); ... ... }; }; Figura 11. Descrição parcial do conjunto de instrução para o processador BIP-II Outras informações referentes à definição do conjunto de instrução utilizando o ArchC, podem ser encontrada em The ArchC Team (2007a) e The ArhcC Team (2007b). 2.5.2.2 Descrição dos Comportamentos Segundo The ArchC Team (2007b), a definição do comportamento de uma instrução é descrita em linguagem SystemC/C++ e pode ser realizada em três níveis: • Genérico: descreve o comportamento executado por todas as instruções; • Formato: descreve o comportamento executado por todas as instruções do formato de instrução especificado; e • Instrução: descreve o comportamento executado apenas pela instrução especificada. Assim, o comportamento de uma instrução é definido por uma hierarquia de comportamentos, sendo feito primeiramente pelo comportamento genérico associado, seguido pelo comportamento do formato e pelo comportamento específico da instrução. 42 Na Figura 12, é possível verificar os três níveis de hierarquia de comportamento para execução da instrução add. O comportamento genérico é indicado pelo parâmetro de função instruction. No exemplo, a cada instrução executada, o valor da variável global do ArchC ac_pc é incrementado em 2 18 . O comportamento do formato de instrução é indicado pelo parâmetro com o nome do formato, definido previamente. No exemplo, o formato em parâmetro é o Type_I e na função, a cada instrução deste formato, são atualizados os valores dos registradores Z e N. O comportamento exclusivo da instrução add é definido pelo parâmetro com o nome da instrução. No exemplo, a instrução acessa o valor do registrador ACC através do método read e grava um valor através do método write. O exemplo também utiliza instruções exclusivas da linguagem como printf para imprimir resultados na tela durante a simulação. Outras informações referentes ao comportamento do conjunto de instruções utilizando o ArchC, podem ser encontradas em The ArchC Team (2007a) e The ArhcC Team (2007b). O código fonte completo da descrição comportamental do BIP-II está disponível no Apêndice A.3. 18 isso porque o ArchC trata os dispositivos de armazenamento em endereçamento byte-a-byte, assim são necessário o incremento de 2 ao PC para equivaler ao tamanho da palavra no BIP II (16 bits) 43 //!Generic instruction behavior method. void ac_behavior( instruction ){ ac_pc = ac_pc + 2; }; //----------------------------//! Instruction Format behavior methods. void ac_behavior( Type_I ){ //Atualiza o Status //----------------------------if (ACC.read()==0) Z.write(1); else Z.write(0); if (ACC.read()<0) N.write(1); else N.write(0); } //----------------------------//!Instruction add behavior method. void ac_behavior( add ){ printf("ADD 0x%x + 0x%x\n", ACC.read(), memRAM.read(operand) ); ACC.write(ACC.read()+(memRAM.read(operand)&0xFFFF)); } //----------------------------- Figura 12. Descrição parcial do comportamento do conjunto de instrução do processador BIP-II 44 3 DESENVOLVIMENTO Esta seção tem por objetivo apresentar o projeto e o desenvolvimento da solução proposta conforme discutido na seção 1.1. A Seção 3.1 apresenta de maneira abstrata os requisitos definidos no projeto do µBIP. A Seção 3.2 apresenta a especificação da arquitetura, já a Seção 3.3 apresenta a especificação da organização do µBIP e dos periféricos. Na Seção 3.4 é apresentada a implementação do modelo no ArchC e na Seção 3.5 a implementação do modelo em VHDL. 3.1 Análise de Requisitos Para definir os requisitos do microcontrolador proposto, foi feita uma consulta a professores, técnicos e engenheiros da área de sistemas embarcados, questionando-os sobre as características fundamentais para um microcontrolador visando sua aplicação no âmbito educacional. Foram recebidas respostas de nove pessoas que opinaram sobre os requisitos listados abaixo (em parênteses, o percentual de respostas positivas): • Inclusão de novas instruções: 1. Instruções de lógica booleana (100% sim) 2. Instruções de deslocamento lógico (78% sim) 3. Instruções de deslocamento aritmético (33% sim) 4. Instruções de manipulação de bit (78% sim) 5. Instrução de ativação do modo sleep (11% sim) 6. Suporte a chamadas de procedimentos (67% sim) • Periféricos básicos a serem integrados: 1. Pinos de E/S unidirecionais (56% sim) 2. Pinos de E/S bidirecionais (78% sim) 3. Pino de interrupção sensível à borda (78% sim) 4. Pino de interrupção sensível ao nível (56% sim) 5. Temporizador programável (100% sim) 6. Contador de pulsos (33% sim) 7. Temporizador watchdog (33% sim) 8. Prescaler para temporizadores (56 % sim) 9. Conversor A/D (56% sim) 10. Interface de comunicação serial (78%) Além da indicação de periféricos, os consultados também retornaram com as características e/ou tipo desejável desses periféricos. A pesquisa completa está disponível no Apêndice B . Com base nessa pesquisa e nos princípios de projeto da família de processadores BIP, foram identificados os requisitos que definiram as diretrizes a serem seguidas durante o projeto e desenvolvimento do µBIP. Também foi levada em consideração a complexidade da inclusão das características consultadas na pesquisa frente ao tempo disponível para a implementação deste projeto dentro do contexto de um Trabalho de Conclusão de Curso. Algumas características foram definidas como opcionais, podendo ser incluídas posteriormente. Requisitos Funcionais (RF) • RF01: O µBIP deverá ter suporte para as seguintes classes de instrução: (a) transferência de dados; (b) aritmética; (c) lógica booleana; (d) desvios; (e) deslocamento lógico; (f) manipulação e teste de bits; (g) suporte a procedimentos; e (h) controle. • RF02: O µBIP deverá ter pelo menos os seguintes periféricos: (a) pinos de E/S bidirecionais com interrupção sensível à borda; e (b) temporizador programável com prescaler, podendo ser estendido para incluir (pela ordem): (i) porta de comunicação serial; (ii) conversor A/D; (iii) contador de pulsos; e (iv) temporizador watchdog. Requisitos Não-Funcionais (RNF) • RNF01: O µBIP deverá estender a arquitetura da família de processadores BIP, assim deverá ser baseado nas diretrizes dessa família. • RNF02: O µBIP deverá ter uma arquitetura simples o suficiente para facilitar o aprendizado de seu funcionamento pelos usuários. • RNF03: O µBIP deverá ter uma arquitetura extensível. 46 • RNF04: O simulador de conjunto de instruções deverá ser implementado no ArchC19. • RNF05: O modelo sintetizável do µBIP deverá ser implementado em VHDL20. 3.2 Especificação da Arquitetura O objetivo desta seção é especificar os atributos arquiteturais presentes no microcontrolador µBIP. Por ser uma extensão da família de processadores BIP, o µBIP herda diversas características e incrementa outras. As subseções a seguir descrevem tais atributos arquiteturais e finaliza com um resumo da arquitetura do µBIP. 3.2.1 Tamanho da Palavra e Tipo de Dados O tamanho da palavra de dados e palavra de instrução no µBIP é de 16 bits. O tipo dado suportado é o tipo Inteiro com sinal de 16 bits que comporta valores entre -32768 e +32767 21 . Portanto, quanto aos aspectos de tamanho de palavra e tipo de dados, o µBIP conserva aqueles utilizados no BIP II, apresentado anteriormente. 3.2.2 Espaços de Endereçamento O espaço de endereçamento de memória de instrução no µBIP é limitado pelas instruções de desvio, que utilizam um operando de 11 bits para informar um endereço absoluto do salto. Com isso, é possível endereçar até 2K (211) de instruções. 22 O espaço de endereçamento da memória de dados também é de 11 bits, o que permite endereçar até 2K endereços. Porém, este espaço é divido com o espaço de endereçamento dos periféricos (ver Figura 13). Isso porque o método utilizado é o de E/S mapeada em memória. Segundo Vahid e Givargis (2002, p. 144-146), o método de E/S mapeada em memória utiliza uma parte de um espaço de endereçamento já existente e não há a necessidade da inclusão de 19 No projeto do µBIP, optou-se pela ADL ArchC, pois esta é baseada na linguagem de modelagem de sistemas SystemC utilizada no LSED, laboratório a qual esse trabalho está vinculado. 20 Durante a fase de projeto do µBIP, optou-se pelo VHDL, pois é a HDL utilizada na universidade a qual esse trabalho está vinculado tanto no ensino quanto no LSED. 21 Para versões posteriores, é considerada a possibilidade de incluir suporte a inteiros de 32 bits, o que não será feito neste momento para limitar a complexidade desta versão. 22 Durante a fase de projeto do µBIP, foi cogitada a utilização de instruções de saltos com desvios relativos ao PC, o que permitiria desviar para posições mais distantes por meio de uma seqüência de salto. Porém, isso implicaria em aumentar a complexidade da arquitetura (mais modos de endereçamento) e da organização. 47 instruções para comunicar com os periféricos. Também foi cogitado o método de E/S padrão (também conhecido como E/S mapeada em E/S), o qual segundo Vahid e Givargis (2002, p.144146) requer um fio adicional no barramento para indicar se o acesso é ao periférico ou à memória de dados, além de instruções exclusivas para manipular os periféricos (normalmente a instrução IN para leitura e OUT para escrita). Durante a fase de projeto optou-se pela E/S mapeada em memória por dois motivos: (i) simplicidade, pois usa as mesmas instruções para manipular variáveis de memória e periféricos, além exigir poucas alterações em nível de hardware; e (ii) economia de instruções, já que no método E/S padrão utiliza instruções específicas. Portanto, em relação ao espaço de endereçamento dos dados, o µBIP possui 1K-palavra destinados a memória de dados e 1K-palavras para registradores de E/S. A vantagem dessa divisão ao meio deve-se principalmente ao fato de utilizar apenas um bit do endereço para identificar se o acesso refere-se à memória ou à E/S, como mostra a Figura 13. Figura 13. Espaçamento de Memória no µBIP Conforme mostra a Figura 14, a parte destinada à E/S mapeia os registradores dos periféricos do µBIP que estão visíveis ao programador. Esses registradores mantêm informações tais como: (i) configuração da direção dos pinos de E/S; (ii) estados dos pinos de E/S; (iii) valor de contagem do temporizador; e (iv) configuração do prescaler. Esses registradores serão discutidos mais adiante neste texto. 48 Figura 14. Organização da Memória de E/S 3.2.3 Registradores A CPU do µBIP possui os seguintes registradores especiais: (i) PC (Program Counter), que contém o endereço da instrução corrente; (ii) ACC (Accumulator), que contém o resultado da Unidade Funcional23 (ou UF); (iii) STATUS, que contém informações sobre o resultado da operação da ULA; (iv) INDR (Index Register), que contém o índice do vetor, utilizado em instruções de manipulação de vetores; e (v) SP (Stack Pointer), que aponta para o topo da pilha de suporte à chamada de procedimentos. O fato do PC apontar para instrução corrente e não para a próxima instrução é devido à ausência de um registrador de instrução, já que sua implementação é baseada em uma abordagem monocíclica, semelhante à implementação MIPS monociclo descrita por Patterson e Hennessy (2000) e já adotada no BIP II. O registrador de STATUS do µBIP possui os seguintes flags: (i) Z, que indica se o resultado da operação na ULA é zero; e (ii) N, que indica se o resultado da operação na ULA é um número negativo; e (iii) C, que indica se ocorreu um carry-out ou borrow em instruções aritméticas. Maiores informações sobre os registradores estão disponibilizadas no Apêndice H . 23 A Unidade Funcional no µBIP é composta de uma ULA e dois barrel shifters para realizar o deslocamento associado às instruções SLL e SRL. 49 3.2.4 Formatos de Instrução O µBIP possui um único formato de instrução composto de 5 bits para o código da operação e 11 bits para o operando, conforme mostra a Figura 15. Com esse operando, é possível endereçar até 2K posições de memória, para instruções que utilizam o operando como endereço de memória; e representar constantes com valores no intervalo de –1024 a +1023, para instruções que utilizam o operando imediato como já mencionado antes. 15 14 13 12 11 10 Cód. Operação 9 8 7 6 5 4 Operando 3 2 1 0 Figura 15. Formato de instrução no µBIP Esse formato de instrução considera um operando implícito que é o registrador ACC e outro operando explícito dado pelos 11 bits da instrução. Há instruções baseadas no formato que não utilizam o operando explícito, como, por exemplo, a instrução de controle HLT. Na fase de projeto do µBIP, foi cogitada a presença de instruções para teste e manipulação de bits como Bit-Set, Bit-Clear e Bit-Test. Para suprir a necessidade desses tipos de instrução seria necessário o acréscimo de mais um formato de instruções com dois campos, um para o valor do bit e outro para endereço do bit. Porém, após análise, foi constatado que essas instruções geravam uma complexidade maior ao modelo e que, na ausência desse tipo de instrução, as instruções da classe lógica booleana poderiam ser utilizadas para produzir a mesma funcionalidade. 3.2.5 Modos de Endereçamento A arquitetura do processador possui três modos de endereçamentos: (i) Direto, no qual o operando refere-se a um endereço efetivo da memória de dados; e (ii) Imediato, no qual o operando é uma constante de dados; e (iii) Indireto, no qual o operando é um endereço base de um vetor que será somado com o registrador INDR para determinar um endereço efetivo da memória de dados, como representado na Figura 16. Destaca-se que muitas das instruções possuem um segundo operando implícito que é o ACC (ex. instruções aritméticas). 50 Figura 16. Modo de endereçamento Indireto 3.2.6 Conjunto de Instruções O conjunto de instruções do µBIP é uma extensão do conjunto de instruções do BIP II, apresentado previamente na Tabela 2, acrescido de instruções das seguintes classes: (i) lógica booleana; (ii) deslocamento lógico; (iii) manipulação de vetores; e (iv) suporte a procedimentos. Um resumo do conjunto de instruções é apresentado na Tabela 5, a seguir, nas quais é possível verificar como as instruções interferem no valor dos registradores ACC, STATUS e PC. Uma descrição mais completa do conjunto de instruções do µBIP é apresentado no Apêndice C . O conjunto de instruções do µBIP preserva os mnemônicos adotados no BIP II. Esses mnemônicos são semelhantes aos utilizados pelo processador MIPS (PATTERSON; HENNESSY, 2000). Outra característica que visa à simplicidade está nos opcodes das instruções. Como pode ser observado na Tabela 5, as instruções que executam a mesma operação, mas usando modos de endereçamento diferentes, como LD e LDI, ADD e ADDI, SUB e SUBI, AND e ANDI, OR e ORI e XOR e XORI possuem uma variação no opcode apenas no bit 0, sendo 0 para operando de memória (modo de endereçamento direto) e 1 operando imediato (modo de endereçamento imediato, como por exemplo: LD=00010 e LDI=0001124. O conjunto de instruções do µBIP possui 29 instruções separadas em 9 classes. O opcode presente nos formatos de instruções é de 5 bits, o que permite codificar até 32 instruções (25), ou seja, restam ainda 3 opcodes não utilizados para novas instruções. 24 A escolha por essa relação foi feita já na especificação da arquitetura do BIP I e apoiou-se no fato de que 0 possui formato que remete ao D (Direto), enquanto que o 1 remete ao I (imediato). Entende-se que essa escolha facilita o aprendizado dos opcodes pelos alunos. 51 A classe de instrução suporte a procedimentos é baseada na solução utilizada na arquitetura PIC16 da Microchip (2001). Nela, quando ocorre uma chamada de procedimentos (ou uma interrupção), o endereço da próxima instrução a ser executada após o retorno do procedimento é armazenado no topo de uma estrutura de pilha (Top of Stack, ou ToS) dedicada exclusivamente para este fim. Essa pilha não é mapeada no espaço de memória, pois é implementada como uma estrutura de hardware tipo LIFO (Last-In, First-Out) baseada em registradores com uma profundidade limitada definida por um parâmetro de projeto no processo de síntese do processador. Tabela 5. Conjunto de instruções do µBIP Opcode 00000 00001 00010 00011 00100 00101 00110 00111 Instrução HLT STO LD LDI ADD ADDI SUB SUBI operand operand operand operand operand operand operand 01000 BEQ operand 01001 BNE operand 01010 BGT operand 01011 BGE operand 01100 BLT operand 01101 BLE operand Flags Z,N,C Z,N,C Z,N,C Z,N,C Operação e atualização do PC Desabilita atualização do PC PC ← PC Memory[operand] ← ACC ACC ← Memory[operand] ACC ← operand ACC ← ACC + Memory[operand] ACC ← ACC + operand ACC ← ACC – Memory[operand] ACC ← ACC – operand PC PC PC PC PC PC PC ← ← ← ← ← ← ← PC PC PC PC PC PC PC + + + + + + + 1 1 1 1 1 1 1 Se (STATUS.Z=1) então PC ← endereço Se não PC ← PC + 1 Se (STATUS.Z=0) então PC ← endereço Se não PC ← PC + 1 Se (STATUS.Z=0) e (STATUS.N=0) então PC ← endereço Se não PC ← PC + 1 Se (STATUS.N=0) então PC ← endereço Se não PC ← PC + 1 Se (STATUS.N=1) então PC ← endereço Se não PC ← PC + 1 Se (STATUS.Z=1) ou (STATUS.N=1) então PC ← endereço Se não PC ← PC + 1 52 Tabela 5. Conjunto de instruções do µBIP (continuação) Opcode 01110 01111 10000 10001 10010 10011 10100 10101 10110 10111 11000 11001 11010 11011 11100 3.2.7 Instrução JMP operand NOT AND operand ANDI operand OR operand ORI operand XOR operand XORI operand SLL operand SRL operand STOV operand LDV operand RETURN RETINT CALL operand Flags Operação e atualização do PC PC ← endereço Z,N Z,N Z,N Z,N Z,N Z,N Z,N Z,N Z,N ACC ← NOT(ACC) ACC ← ACC AND Memory[operand] ACC ← ACC AND operand ACC ← ACC OR Memory[operand] ACC ← ACC OR operand ACC ← ACC XOR Memory[operand] ACC ← ACC XOR operand ACC ← ACC << operand ACC ← ACC >> operand Memory[operand + INDR] ← ACC ACC ← Memory[operand + INDR] PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← PC + 1 PC ← ToS PC ← ToS PC ← operand ToS ← PC+1 Resumo da Arquitetura µBIP Tabela 6. Arquitetura do µBIP Tamanho da palavra de dados Tipos de dados Tamanho da palavra de instrução Formato de instrução 16 bits Inteiro de 16 bits com sinal –32768 a +32767 16 bits Modos de endereçamento Direto: o campo Operando é um endereço efetivo da memória de dados Imediato: o campo Operando é uma constante de dado Indireto: o campo Operando é um endereço base de um vetor que é somado ao INDR para o cálculo de um endereço efetivo da memória de dados ACC: acumulador PC: contador de programa STATUS: registrador de Status INDR: registrador de índice SP: apontador do topo da pilha Armazenamento: STO Carga: LD e LDI Aritmética: ADD, ADDI, SUB e SUBI Lógica booleana: AND, OR, XOR, ANDI, ORI, XORI e NOT Controle: HLT Desvio: BEQ, BNE, BGT, BGE, BLT, BLE e JMP Deslocamento Lógico: SLL e SRL Manipulação de vetor: LDV e STOV Suporte a procedimentos: RETURN, RETINT e CALL Registradores Classes de instrução 15 14 13 12 11 10 Cód. Operação 53 9 8 7 6 5 4 Operando 3 2 1 0 3.3 Especificação da Organização A organização do µBIP é baseada na organização do BIP II, mantendo a estrutura com memórias de instruções e dados separadas (tipo Harvard, mostrada anteriormente na Figura 6 (a)) e a arquitetura baseada em acumulador (previamente ilustrada na Figura 5 (b)). A Figura 17 apresenta uma visão abstrata da organização interna do µBIP. A figura apresenta a CPU e os barramentos com as memórias de dados e de instruções separadas, além dos periféricos ligados no mesmo barramento da memória de dados, conforme mencionado na Subseção 3.2.2 . Figura 17. Visão abstrata da organização do µBIP A Figura 18 mostra uma visão detalhada da organização, na qual é visível o aumento no número de sinais de controles e a adição de novos componentes, incluindo: (i) uma unidade funcional que executa operações de aritmética, lógica e de deslocamento, substituindo a unidade aritmética do BIP II. (ii) uma pilha na unidade de controle para suporte a procedimentos e interrupções; (iii) uma unidade de manipulação de vetores no caminho de dados (ela inclui o registrador INDR); (iv) uma interface de acesso via barramento da memória de dados aos registradores de propósito especiais (SFR – Special Function Register) dos periféricos integrados; (v) um controlador de interrupções. 54 1 1 0 data_in addr_in 0 Figura 18. Visão detalhada da organização da CPU do µBIP Unidade Funcional A Unidade Funcional presente no caminho de dados do µBIP (Figura 18) é a união de uma unidade aritmética (soma e subtração) com uma unidade lógica (funções lógicas: AND, OR, NOT e XOR) e também uma unidade de deslocamento lógico (deslocamento a esquerda e a direita). Uma visão da Unidade Funcional é apresentada na Figura 19. A entrada operation de 3 bits permite identificar a operação a ser realizada pela Unidade Funcional, conforme os códigos apresentados na Tabela 7. Destaca-se que a Unidade Funcional possui as três saídas de condição que compõem o registrador STATUS: C, Z e N, conforme já descrito. 55 Figura 19. Organização da Unidade Funcional do µBIP Tabela 7. Código de operação da Unidade Funcional Operation Operação 000 001 010 011 100 101 110 111 Instruções Soma Subtração Função lógica E Função lógica OU Função lógica XOR Função lógica NOT Deslocamento Lógico para esquerda Deslocamento Lógico para direita ADD SUB AND OR XOR NOT SLL SRL e e e e e ADDI SUBI ANDI ORI XORI Pilha A Pilha (Stack) incluída na Unidade de Controle tem a finalidade de guardar o endereço da instrução seguinte à instrução CALL, mantendo assim o endereço de retorno da função. A instrução RETURN apenas desempilha o valor colocado pela instrução CALL e restaura o conteúdo do PC, fazendo assim que o programa continue normalmente. A Pilha possui um hardware simples, dotado de uma memória do tipo LIFO, um somador/subtrator e um registrador para indicar a posição do topo da pilha (SP – Stack Pointer), conforme mostra a Figura 20. 56 Stack n-1 ... ... ... 0 ena op dout SP -/+ din wren 1 Figura 20. Organização da Pilha Manipulação de vetores Esse bloco viabiliza a construção de aplicativos que utilizam vetores e está relacionado às instruções LDV e STOV. A lógica de seu funcionamento já foi apresentada na Seção 3.2.5 e na Figura 16. O hardware necessário para a implementação desse módulo é mostrado na Figura 21, como mostrado trata-se de um registrador (INDR) e um somador. A entrada data_in e wr_indr são utilizados para armazenar o índice no registrador INDR e isso realizado através da instrução STO. A entrada operand contém o operando da instrução. A entrada select é utilizada para definir se o resultado do modulo (addr) será apenas a entrada operand ou será a somada do operand com o valor armazenado em INDR. 57 Figura 21. Organização do módulo de manipulação de vetores Periféricos: Pinos de E/S O µBIP possui duas portas com 16 pinos de E/S bidirecionais e com controle individual de direção (ou seja, diferentes bits de uma mesma porta podem ser configurados como de entrada ou de saída). A notação utilizada para identificar a porta é dada por “portX” onde X é o identificador único da porta como, por exemplo, “port0”. A manipulação com os pinos de entrada e saída é feita através de instruções LD e STO nos registradores portX_dir e portX_data. O registrador portX_dir é responsável por determinar a direção (entrada ou saída) dos pinos da porta. Quando um bit correspondente a um pino é setado (= 1) no registrador portX_dir, significa que este atuará como entrada, e quando em ‘0’ atuará como saída. Para Souza (2004, p. 42), uma maneira prática de o usuário memorizar esta configuração é associar o 0 (zero) à letra O de OUT (saída) e o 1 (um) à letra I de INPUT (entrada). O pino 0 da port0 está associado a um bloco chamado “Edge Detector”, responsável por ativar uma interrupção caso seja detectada uma borda de subida ou descida nesse pino, conforme configurado no registrador mcu_config. 58 Temporizador O µBIP possui um temporizador de 16 bits com prescaler. Os registradores utilizados pelo temporizador são: (i) trm0_config, que contem a configuração do prescaler nos bits (0 a 2); e (ii) tmr0_value, que contem o valor atual do contador. Por ser um contador de 16 bits, o estouro do temporizador ocorre a cada 65.536 ciclos, porém o usuário pode multiplicar o período de estouro do temporizador utilizando o prescaler conforme a Tabela 8. A cada estouro do temporizador é gerada um sinal de interrupção. Tabela 8. Configuração do prescaler no registrador tmr0_config Prescaler 000 001 010 011 100 101 110 111 Escala 1:1 1:2 1:4 1:8 1:16 1:32 1:64 1:128 Ciclos para um estouro 65.536 131.070 262.140 524.280 1.048.560 2.097.120 4.194.240 8.388.480 Controlador de Interrupções (IC) O controlador de interrupções do µBIP possui apenas duas entradas de interrupção associadas: (i) Interrupção por detecção de borda no pino 0 da port0; e (ii) Estouro do temporizador. As interrupções recebidas pelo IC são armazenadas em suas posições correspondentes no registrador int_status e caso esteja ativado (=1) o bit correspondente no registrador int_config, é gerada uma interrupção para a CPU e o controle fica aguardando o sinal de ACK. Esse sistema é semelhante ao utilizado nos microcontroladores PIC® (MICROCHIP, 2001). A Figura 22 apresenta um fluxograma do funcionamento do Controlador de Interrupções, Como mostra a figura, na recepção de uma interrupção pelo controlador, é verificado primeiramente se a chave geral de interrupções está ativa. Se sim, então é verificado se a chave individual está ativa também e, caso seja positivo, então é enviada uma interrupção à CPU. No atendimento de uma interrupção, o controlador desabilita temporariamente a chave geral para impedir que ocorram novas interrupções. Sempre que ocorre uma interrupção, a CPU salva o contexto (registrador PC) na pilha e redireciona o PC para o endereço 0x001 da memória de 59 instruções, onde deve estar a rotina de tratamento de interrupções. O tratamento de prioridade de interrupções e limpeza do flag do int_status deve ser feito manualmente pelo usuário dentro da rotina de tratamento de interrupção. O retorno de uma interrupção acontece após a execução da instrução RETINT. Figura 22. Fluxo do Controle de Interrupção Fonte: Adaptado de Souza(2004, p. 135); Barramento de Dados e E/S No µBIP, a integração dos periféricos com a CPU é realizada através de um barramento com os seguintes grupos de vias: (i) addr: que possui o endereço de um registrador interno de um periférico ou endereço de uma posição de memória; (ii) din: possui o dado a ser escrito no 60 endereço indicado por addr; (iii) wr_data: permite a escrita do dado din no endereço addr; (iv) dout: é uma via individual por periférico que possui o dado a ser retornado para a CPU (na sua entrada de dados, a CPU possui um multiplexador que escolhe o dado de entrada a partir do endereço dado por addr); e (v) rd_data: que informa ao periférico para colocar no canal de saída dout o conteúdo do registrador dado por addr. A Figura 23 apresenta este cenário. Com esse sistema de barramento, o incremento de um novo periférico implica apenas em adicionar uma via no multiplexador do barramento de dados (chamado de Data Bus Mux). Figura 23. Integração da CPU com os periféricos e Memórias. 61 3.4 IMPLEMENTAÇÃO DO µBIP NO ARCHC Nesta seção, é apresentada a implementação da arquitetura do µBIP no ArchC visando validar o conjunto de instruções e gerar automaticamente o montador, o ligador e o simulador ISA. Como visto anteriormente, existem dois blocos principais no ArchC e eles são apresentados nas subseções a seguir. Ao final, mostra-se um levantando das restrições dessa implementação. 3.4.1 Recursos da arquitetura A implementação dos recursos da arquitetura foi realizada em um único arquivo nomeado “ubip.ac”. O código fonte referente a este arquivo é apresentado na Figura 24. Uma das limitações encontradas na implementação do modelo no ArchC está na declaração das memórias, pois é permitida apenas a declaração de memórias orientadas a byte, sendo que na família BIP as memórias são orientadas a palavra. Dessa forma, as memórias de dados e de instruções foram declaradas contendo “4K” (linhas 3 e 4), ou seja 4Kbyte ou 2K-palavras. No trecho de código apresentado, declaram-se também os principais registradores da arquitetura (linha 5), o tamanho da palavra de 16 bits (linha 6) e a forma de ordenação dos bytes no formato big-endian (linha 9). 1 2 3 4 5 6 7 8 9 10 11 /********************** ubip.ac *********************/ AC_ARCH(ubip){ ac_mem memRAM:4K; //4Kbyte/2K-Words ac_mem memROM:4K; //4Kbyte/2K-Words ac_reg PC, ACC, STATUS; ac_wordsize 16; ARCH_CTOR(ubip) { ac_isa("ubip_isa.ac"); set_endian("big"); }; }; Figura 24. Implementação do µBIP no ArchC – Recursos da Arquitetura. 3.4.2 Arquitetura do conjunto de instruções A implementação da arquitetura do conjunto de instruções (AC_ISA) foi realizada em quatro arquivos (i) ubip_isa.ac, que contem informações sobre o conjunto de instruções e codificação assembly; (ii) ubip_isa.cpp, que contém o comportamento de cada instrução durante o processo de simulação; (iii) ubip_address.h, que contém algumas constantes utilizadas dentro do arquivo ubip_isa.cpp; e (iv) modifiers: que permite adicionar algumas funções para o montador/ligador. A seguir são apresentados detalhamentos desses arquivos. 62 Arquivo ubip_isa.ac Como mencionado, esse arquivo possui informações sobre o conjunto de instruções que são relevantes tanto para a criação do montador e do ligador como também do simulador ISA. A Figura 25 apresenta parte do código deste arquivo e a numeração na lateral esquerda da figura é apenas ilustrativa. Primeiramente, na linha 2 é definido o formato de instrução válido denominado INS_FORMAT com os campos op de 5 bits e operand de 11, igualmente definidos na Figura 15. Após definido o formato de instrução, são atribuídas todas as instruções válidas para este formato como mostrado nas linhas 4 a 11. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 AC_ISA(ubip){ ac_format INS_FORMAT ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> ac_instr<INS_FORMAT> = "%op:5 %operand:11"; //Formatos hlt; // CONTROLE //TRANSFERENCIA DE DADOS sto, ld, ldi; add, addi, sub, subi; // ARITMÉTICA beq, bne, bgt, bge, blt, ble, jmp; // DESVIOS not, and, andi, or, ori, xor, xori;// LÓGICA B. sll, srl; // DESLOCAMENTO stov, ldv; // VETORES return, retint, call; // SUPORTE A PROCEDIMENTOS ac_asm_map ubipSFR { ""[0..2047] = [0..2047]; //Todas as posicoes de memoria "$"[0..2047] = [0..2047]; //Todas as posicoes de memoria "$port0_dir" = 1024; //Configuracao dos pinos de E/S "$port0_data" = 1025; //Valores dos pinos de E/S "$port1_dir" = 1026; //Configuracao dos pinos de E/S "$port1_data" = 1027; //Valores dos pinos de E/S "$tmr0_config"= 1040; //Configuracao do Preecaler do Timer0 "$tmr0_value" = 1041; //Valor do contador do Timer0 "$int_config" = 1056; //Configuracao das Interrupcoes "$int_status" = 1057; //Indica quais interrupcoes estao ativas "$mcu_config" = 1072; //Opcoes "$indr" = 1073; //Auxiliar para Vetores } ISA_CTOR(ubip) //--- FORMATO ASSEMBLY E OPCODE--{ sto.set_asm("sto %ubipSFR", operand); sto.set_asm("sto %exp", operand); sto.set_decoder(op=0x01); not.set_asm("not", operand=0); not.set_decoder(op=0x0F); beq.set_asm("beq %addr(align)", operand); beq.set_decoder(op=0x08); ... pseudo_instr("psto %ubipSFR, %imm") //psto $port0_data, 0xAA { "ldi %1"; "sto %0"; } ... Figura 25. Implementação do µBIP no ArchC – ubip_isa.ac 63 A definição presente nas linhas 13 a 27 permite criar um conjunto de constantes que durante o processo de montagem são substituídas pelos valores correspondentes. Esse recurso é utilizado principalmente para declarar os registradores visíveis ao programador, como por exemplo, na linha 17, é definido que a constante $port0_dir refere-se ao endereço 1024. Já na linha 16, é definido um intervalo de valores que permite que o usuário referencie posições de memória por um cifrão ($) seguido pelo número decimal, como, por exemplo, $15. Na linha 30, é definida a sintaxe assembly através da palavra reservada set_asm para a instrução STO. Nela, o campo operand do formato de instrução é representado por uma constante definida em $ubipSFR. Dessa maneira, as instruções reconhecidas pelo montador são, por exemplo: STO $port0_data. Na linha 31, é feita uma sobrecarga de sintaxe, permitindo também que o campo operand do formato seja um valor do tipo exp (pré-definido pelo ArchC) que aceite, por exemplo, usar variáveis declaradas na seção .data, rótulos e constantes inteiras no formato hexadecimal. Agora, o montador reconhece também as seguintes instruções: STO var1; STO 0x001. Na linha 32, é utilizada a instrução ArchC set_decoder para atribuir um valor a um dos campos do formato de uma instrução. Nesta linha, o campo op do formato de instrução recebe a constante indicada. Assim, a instrução assembly STO 0x04F atribui o valor 0x01 para o campo op do formato e 0x04F para o campo operand. Em instruções onde não há o operando explicito, como no caso da instrução NOT, o valor campo operand é atribuído com zero como mostra a linha 34. Como mencionado anteriormente o ArchC trata as memórias orientadas a byte e não a palavras. Isso resultou em algumas funções extras para lidar com essa restrição. Uma dessas funções, denominada align, está presente no arquivo modifiers e é utilizada para realinhar o rótulo utilizado na instrução BEQ, considerando uma memória orientada a palavras. Outro recurso disponível pelo ArchC e utilizado neste projeto são as pseudo-instruções. Esse recurso permite declarar instruções assembly que durante o processo de montagem são substituídas pelas instruções nativas da linguagem, conforme declarado. No projeto, esse recurso foi utilizado para mostrar a capacidade do ArchC e foram criadas apenas algumas pseudo-instruções. Em destaque, nas linhas 40 a 44, é declarada a pseudo-instrução psto que permite carregar uma 64 constante em uma posição de memória de dados. Essa pseudo-instrução possui dois campos, um do tipo $ubipSFR que indica a posição da memória de dados e outro imediato que contem o valor a ser armazenado, e durante a montagem é substituída por duas instruções nativas: ldi %1 e sto %0. O termo %x, onde x é um número, é utilizado para referenciar a posição do campo da pseudo-instrução. Arquivo ubip_isa.cpp Este arquivo possui informações sobre o comportamento das instruções e tem papel fundamental na criação do simulador ISA. Além de funções que descrevem o comportamento das instruções, foram criadas outras funções para auxiliar todo o processo. A Figura 26 apresenta algumas das funções utilizadas para manipular as memórias de dados e de instruções devido à limitação de endereçamento byte-a-byte. O termo AC_WORDSIZE é uma constante que possui a quantidade de bits de uma palavra declarada previamente no arquivo ubip.ac. Outra limitação presente na versão 2.0 do ArchC é que todos os recursos da arquitetura que foram utilizados dentro de funções complementares devem ser passadas por parâmetro não tendo acesso global a eles. A função DataMemoryRead, por exemplo, que recebe como parâmetro uma memória e um endereço, calcula o endereço correspondente em uma memória byte-a-byte e retorna a palavra. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //======================================================== ac_word ProgramMemoryRead(ac_memory& memROM, unsigned mem_address ) { return memROM.read(mem_address*(AC_WORDSIZE/8)); };//======================================================== ac_word DataMemoryRead(ac_memory& memRAM, unsigned mem_address ) { return memRAM.read(mem_address*(AC_WORDSIZE/8)); };//======================================================== void DataMemoryWrite(ac_memory& memRAM, unsigned mem_address, ac_word datum ) { memRAM.write(mem_address*(AC_WORDSIZE/8), datum); };//======================================================== void set_PC(ac_reg<unsigned>&PC, unsigned value) { PC = value*(AC_WORDSIZE/8); };//======================================================== Figura 26. Implementação do µBIP no ArchC – Funções Auxiliares (ubip_isa.cpp) Outras funções auxiliares foram implementadas para separar e melhorar a visibilidade e entendimento do código, como por exemplo, funções para setar os flags do registrador STATUS. 65 Na Figura 27 é apresentada a implementação do comportamento da instrução ADD. Essa implementação demonstra o real comportamento da instrução. O primeiro operando da instrução é o próprio acumulador (operando implícito) e o segundo é buscado na memória pelo endereço dado pelo campo operand da instrução, a soma destes dois operandos é armazenada no acumulador. O registrador STATUS é atualizado e o PC é incrementado. Em cada comportamento, é utilizada a função myPrint para gerar e armazenar um log da simulação em um arquivo. É relevante notar que as variáveis declaradas neste comportamento são do tipo ac_Sword, o qual representa um inteiro de 16 bits com sinal. Na figura, as palavras STATUS, PC, ACC e memRAM referem-se aos mesmos declarados no arquivo ubip.ac. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 void ac_behavior( add ){ //Operantion ac_Sword operand1 = ACC.read(); ac_Sword operand2 = DataMemoryRead(memRAM,operand); ac_Sword result = operand1 + operand2; //Update ACC ACC.write(result); //Update Status Register set_status(STATUS, Z, check_zero(result)); set_status(STATUS, N, check_negative(result)); set_status(STATUS, C, check_carry_out(operand1, operand2)); //Increment PC inc_PC(ac_pc); //Output information sprintf(strBuffer,"ACC=0x%04X+0x%04X", (ac_word)operand1, (ac_word)operand2 ); myPrint("add", operand, strBuffer); } void ac_behavior( call ) { //Operantion ac_word oldPC = get_PC(ac_pc)+1; STACK.push(oldPC); set_PC(ac_pc, operand); //Output information sprintf(strBuffer, "Stack.push(0x%04X)", oldPC); myPrint("call", operand, strBuffer); } Figura 27. Implementação do µBIP no ArchC – Comportamento (ubip_isa.cpp) A Figura 27 apresenta também a implementação do comportamento da instrução CALL, o que permite mostrar que há implementada uma estrutura de pilha que permite salvar e recuperar o PC, no exemplo a instrução STACK.push(oldPC) armazena o valor oldPC no top da pilha. A variável oldPC é igual ao valor do PC atual incrementado em uma unidade, ou seja, PC+1. Neste arquivo, ainda estão presentes funções que simulam o comportamento de um temporizador com prescaler e geração de interrupção. Ele também possui a funcionalidade de gerar 66 três arquivos de saída: (i) sim_result.txt, que contém todo o log de simulação ciclo-a-ciclo apresentando dados dos principais registradores e movimentação na memória de dados, conforme mostra o trecho da Figura 28; (ii) sim_ports_result .txt, que contém todos os dados enviados para as portas de E/S, ótimo para verificar resultados de testes; e (iii) program1.vhd, que contém a implementação da memória ROM do µBIP em VHDL com o código do programa simulado. ================ Simulation Start ================= Log save in: sim_result.txt ------------------- Data Memory ----------------------------------| I[0000]=0x1A34 | I[0003]=0x0C01 | I[0006]=0x88FF Instruction Memory --------------| I[0001]=0x0800 | I[0002]=0x88FF | I[0004]=0x1000 | I[0005]=0xB808 | I[0007]=0x0C03 0x0000|0x1A34| ldi 0x234 # ACC=0x0234 operand |PC=0x0001|ACC=0x0234|Z=0x0|N=0x0|C=0x0|M[0x0411]=0x0002 0x0001|0x0800| sto 0x000 # M[0x0000]=0x0234 |PC=0x0002|ACC=0x0234|Z=0x0|N=0x0|C=0x0|M[0x0000]=0x0234|M[0x0411]=0x0003 0x0002|0x88FF| andi 0x0FF # 0x0234 and 0x00FF |PC=0x0003|ACC=0x0034|Z=0x0|N=0x0|C=0x0|M[0x0411]=0x0004 0x0003|0x0C01| sto 0x401 # M[0x0401]=0x0034 |PC=0x0004|ACC=0x0034|Z=0x0|N=0x0|C=0x0|M[0x0401]=0x0034|M[0x0411]=0x0005 0x0004|0x1000| ld 0x000 # ACC=M[0x0000]=0x0234 |PC=0x0005|ACC=0x0234|Z=0x0|N=0x0|C=0x0|M[0x0411]=0x0006 0x0005|0xB808| srl 0x008 # ACC=0x0234>>0x0008 |PC=0x0006|ACC=0x0002|Z=0x0|N=0x0|C=0x0|M[0x0411]=0x0007 0x0006|0x88FF| andi 0x0FF # 0x0002 and 0x00FF |PC=0x0007|ACC=0x0002|Z=0x0|N=0x0|C=0x0|M[0x0411]=0x0008 0x0007|0x0C03| sto 0x403 # M[0x0403]=0x0002 |PC=0x0008|ACC=0x0002|Z=0x0|N=0x0|C=0x0|M[0x0403]=0x0002|M[0x0411]=0x0009 0x0008|0x0000| hlt # ================== Simulation End ================= ------------------- Data Memory ------------------| M[0000]=0x0234 | M[1025]=0x0034 | M[1027]=0x0002 | M[1041]=0x0009 Figura 28. Implementação do µBIP no ArchC – Arquivo de Simulação (ubip_isa.cpp) Arquivo ubip_address.h Este arquivo possui apenas constantes que são utilizadas dentro do arquivo ubip_isa.cpp como, por exemplo, na Figura 27, são utilizadas as constantes Z, N e C definidas nesse arquivo. modifiers Conforme mencionado, são utilizados para realizar deslocamentos nos campos de formatos de instruções como no caso de instruções de desvios que fazem uso para realinhar o endereçamento dos rótulos para memórias baseadas em palavras. 67 3.4.3 Testes e Validações A implementação do ArchC foi testada e validada utilizando as configurações de software apresentadas no Apêndice D .A validação aconteceu de duas maneiras: (i) testes unitários; e (ii) utilização de um testbench pré-definido. Ambos são apresentados nesta seção. Testes Unitários Os testes unitários tiveram como objetivo validar cada instrução do µBIP nas ferramentas do ArchC (montador, ligador e simulador ISA). Para isso, foi realizado um levantamento identificando, para cada instrução, o grupo de instruções necessárias para validá-la, bem como o estado esperado para os registradores e para as memórias após a execução da instrução. Esse levantamento resultou na tabela presente no Apêndice E . Após levantamento, todos os testes foram transcritos para arquivos de código fonte e submetidos ao montador e ao ligador. O arquivo gerado pelo ligador foi então foi submetido ao simulador ISA e os relatórios da simulação foram analisados e comparados com os resultados esperados. Esse processo é representado na Figura 29. Figura 29. Implementação do µBIP no ArchC – Processo de Simulação 68 Validação usando o testbench Em um segundo momento, os testes foram realizados utilizando um conjunto de aplicações (testbench) disponibilizado na página do Dalton Project (THE DALTON PROJECT TEAM, 2001). Trata-se de um conjunto de programas descritos em C++ que já foram utilizados para validar o modelo de processador 8051 e outros processadores. Esse testbench é uma das alternativas indicadas pelo desenvolvedores do ArchC (THE ARCHC TEAM, 2007a). A escolha por essas aplicações de teste deveu-se à sua simplicidade para codificação na linguagem de montagem. Não se poderia escolher um conjunto complexo já que a tradução da linguagem C++ para o assembly do µBIP foi realizada manualmente. Essa “compilação manual” do testbench não levou em consideração nenhuma otimização, apenas a conversão dos testes de maneira rápida e facilitada. A Tabela 9 apresenta uma breve descrição de cada uma das aplicações do testbench, bem como a quantidade de instruções assembly em cada arquivo. Tabela 9. Descrição do testbench Aplicação Descrição Número de instruções cast Converte um número de 16 bits em dois de 8 bits 13 divmul fib gcd int2bin negcnt sort sqroot xram Realiza uma seqüência de divisões e multiplicações Série de Fibonacci Encontra o máximo multiplicador comum entre dois números Transforma um número inteiro para binário Realiza operações com números negativos Realiza uma ordenação de vetor Realiza cálculos de raiz quadrada Realiza operações com todas as posições da memória 85 52 25 20 15 99 62 20 Após a “compilação manual” os testes prosseguiram o mesmo fluxo apresentado na Figura 29. Os resultados das simulações foram conferidos com os resultados esperados também disponíveis em (THE DALTON PROJECT TEAM, 2001). O gráfico apresentado na Figura 30 contém informações sobre o uso de cada instrução nas aplicações do testbench. Como o pacote de testbench é composto por 9 aplicações de teste, logo o valor máximo para cada instrução no gráfico é limitado em 9. Assim, pode-se notar que as instruções LDI, LD, STO e HLT foram usadas em todos os testes, já as instruções RETINT, XOR, XORI, OR e NOT não foram utilizadas nessas aplicações. Conforme tabela apresentada no 69 Apêndice F.10, em resumo, 82% de todo o conjunto de instruções foi validado pelo testbench utilizado. As demais foram validadas apenas pelos testes unitários. Utilização das instruções nos testbenchs LDI LD STO HLT JMP CALL RETURN SUBI ADDI SUB BGE BEQ LDV STOV ADD SLL ANDI BGT SRL ORI AND BLE BLT BNE RETINT XORI XOR OR NOT 0 1 2 3 4 5 6 7 8 9 Figura 30. Utilização das instruções nos testbenchs 3.4.4 Limitações Nesta subseção são apresentadas as limitações do ArchC e da implementação do modelo. A primeira delas, já discutida, refere-se ao fato do ArchC não utilizar tipos de memórias orientadas a palavras e somente byte-a-byte. Isso levou a uma série de implementações descritas anteriormente. Uma limitação da implementação do modelo deve-se à forma de utilização da seção .data disponível no arquivo assembly aceito pelo montador. De uma forma geral, o montador gerado não permite que as variáveis declaradas na seção .data sejam inicializadas. Este processo deve ser feito na seção .text utilizando instruções de LDI e STO. 70 Outra limitação quanto ao modelo deve-se ao fato de que o simulador gerado pelo ArchC serve apenas para simular o conjunto de instruções, estando incapacitado de gerar estímulos que interajam com o simulador. A solução para este problema é a utilização do ARP (ArchC Plataform) disponível em (THE ARCHC TEAM, 2007a). Porém, o seu uso está fora do escopo deste trabalho. 3.4.5 Considerações sobre o uso do ArchC como ferramenta de projeto arquitetural O uso do ArchC nesse projeto teve dois pontos positivos. Primeiramente ele permitiu a validação e revisão da arquitetura do modelo antes da sua implementação em VHDL. Conseguiu-se verificar através do ArchC o funcionamento de cada instrução, a viabilidade da codificação assembly para construções de programas além de madurecer as especificações iniciais do µBIP. Um segundo ponto trata-se do benefício do ArchC em disponibilizar um conjunto de ferramentas (montador, ligador e simulador) que incrementaram o valor final desse trabalho. As ferramentas geradas pelo ArchC serão de grande uso para os usuários finais do µBIP tanto para estudo da arquitetura e organização quanto para implementação de programas para µBIP. A arquitetura proposta para o µBIP e a sua modelagem usando o ArchC foram apresentadas no SIM 2008 (23th South Symposium on Microelectronics), sendo que um artigo foi publicado nos anais do evento (PEREIRA; ZEFERINO, 2008). 3.5 IMPLEMENTAÇÃO DO MODELO VHDL Esta seção tem por objetivo apresentar a implementação do modelo µBIP em VHDL e o seu processo de validação. Para a implementação do modelo, fez-se primeiramente um levantamento dos periféricos e blocos existentes no modelo partindo de uma visão geral do microcontrolador final esperado e aprofundando em detalhes e dividindo o modelo em blocos como mostra a Figura 31, ou seja, uma visão top-down, onde aumenta-se o detalhamento a cada nível. Porém a implementação aconteceu de forma inversa, ou seja, bottom-up dos blocos mais internos para os blocos mais externos. As vantagens da implementação bottom-up são o reaproveitamento de blocos em módulos superiores e a capacidade de se realizar o teste unitário de blocos internos antes da integração com outros módulos. 71 CPU 1 19 Control 2 20 3 21 Datapath Extensão de Sinal STACK Stack in Stack out Op WrEn SFRs SelA 0x 001 0 1 2 3 4 Operand2 Operand1 Decoder 22 5 23 + IC 0x 001 Intr 1 1 0 Opcode 26 27 28 11 29 12 30 13 31 14 32 15 33 16 34 17 35 18 36 wren Operation operand2 Function Unit Shift Left +/- Shift Right C 2 Operation ena Indr 1 0 STATUS is_ vector N is_vector Z C Vector Access addr_out 10 data_in data_out 1 PC C Z N Result WrData Addr 9 SelB SelC addr_in 25 8 0 data_in 7 1 WrData FU_Op ena ACC operand Z N C Z N 24 addr_in 0 µBIP 2 0 6 3 ena 1 4 WrACC Stack_wr Stack_ op WrPC WrACC SelA SelB SelC is_ vector WrData FU_ Op SourcePC Out_ Data Program Memory Wr Addr In_Data Out_Data Data Memory Figura 31. Visão top-down do µBIP A Figura 32 apresenta a hierarquia de arquivos desenvolvidos no projeto que são abordados mais adiante e no Apêndice G . A ferramenta utilizada para implementar e validar o modelo foi a Quartus II® – 7.2 SP3 da fabricante ALTERA®. A escolha é pelo fato dessa ser a mesma ferramenta utilizada no LSED. 72 + ubip + cpu + control - stack + datapath - alu - ram - rom + io_port + io_pin - flip_flop_d_ena - latch_d_ena - timer - interruptcontroller - edge_detector - databus - frequencydivider Figura 32. Hierarquia de arquivos VHDL 3.5.1 Testes e Validação A validação do modelo VHDL aconteceu de duas formas. Primeiramente, cada bloco implementado foi submetido à simulação para validar o seu funcionamento. Em um segundo momento os blocos que foram integrados também foram validados para verificar seus comportamentos após a integração. Neste documento, estão presentes apenas as validações realizadas sobre o bloco de nível mais superior o “ubip.vhd”. A Figura 33 apresenta o diagrama de formas de onda da validação por simulação do modelo VHDL do microcontrolador executando a aplicação cast.s, disponível no Apêndice F.1. Essa aplicação carrega uma palavra de 16 bits no acumulador e depois separa os seus dois bytes, escrevendo-os em duas portas de E/S diferentes. Na figura, destacam-se alguns pontos importantes: 1. O operando zero da instrução LDI (OPCODE = 0x03)é carregado no ACC (por default, já inicializado em 0); 2. As portas de E/S (port0 e port1) são configuradas como saída; 3. O valor 0x1234, de 16 bits, é carregado no ACC por meio de três instruções (LDI, SLL e ORI, de OPCODES 0x03, 0x16 e 0x13, respectivamente); 73 4. O byte menos significativo (0x34) é escrito na saída da port0; 5. É realizado o deslocamento de 8 bits para colocar o byte mais significativo nos bits de 7 a 0 do ACC; e 6. O byte mais significativo (0x12) é escrito na saída da port1. Com esse teste foi possível validar as instruções utilizadas, bem como alguns blocos do modelo, como por exemplo, as portas de E/S. A lista das instruções utilizadas também estão disponíveis no Apêndice F.10. Figura 33. Diagrama de formas de onda da simulação da execução da aplicação cast Outro diagrama de forma de ondas é apresentado na Figura 34. Trata-se de um trecho da execução do testbench fib.s, disponível no Apêndice F.3. Destacam-se alguns pontos importantes nesta simulação (mostra-se uma região intermediária, dos instantes da execução): 1. O registrador de índice INDR é atualizado com o valor do acumulador (9); 2. A instrução LDV (OPCODE = 0x19) é utilizada para carregar um valor de memória, dado pela posição do operando da instrução (4) mais o valor armazenado em INDR (9). Logo, o acumulador é atualizado com o valor armazenado na posição 13 da memória de dados, ou seja, 0x0037; 3. O valor do acumulador é escrito na port0; 74 4. Após a instrução JMP (OPCODE = 0x0E), é possível notar no registrador PC o desvio para o valor do operando da instrução (0x0022); 5. Após a execução do BGE (OPCODE = 0x0B) com o flag Z do registrador STATUS setado o registrador PC recebe o valor do operando da instrução evidenciando o desvio condicional. 1 2 3 4 5 Figura 34. Diagrama de formas de onda da simulação da execução da aplicação fib Um teste mais robusto foi realizado utilizando uma adaptação do exemplo disponível em Souza (2004, p. 140 – 148) denominado “Exemplo 5 – Timer Simplificado”. Em resumo, trata-se de um contador que, a cada segundo, apresenta em um display de 7-segmentos o valor do contador em hexadecimal e utiliza de dois botões como entrada, um para ativar o contador e outro para paralisar ou reiniciar o contador. Esse exemplo utiliza grande parte dos recursos utilizados pelo µBIP como mostra a primeira parte da simulação na Figura 35. 75 3 1 2 4 5 6 7 8 9 Figura 35. Diagrama de formas de onda da simulação da execução da aplicação Exemplo 5 Parte-1 Na Figura 35 destacam-se os seguintes pontos: 1. Instrução JMP (OPCODE = 0x0E) no endereço 0x0000 para o endereço do rótulo “main”. Isto para preservar o endereço 0x0001 para tratamento das interrupções; 2. Configuração da port1 com todos os pinos como saída; 3. Configuração da port0 com todos os pinos como entrada; 4. Funcionamento do bloco de extensão de sinal de acordo com o bit 10; 5. Configuração do prescaler com valor 0x003 - 1:8, ou seja, a cada 8 pulsos o timer é incrementado; 6. Habilitando apenas a interrupção do temporizador timer0; 7. Detectado uma borda de descida. Logo, é gerada uma interrupção; 76 8. A solicitação de interrupção do pino 0 da port0 é armazenada no registrador int_status, porém o controlador de interrupção não gera uma interrupção à CPU pois o bit correspondente no registrador int_config não está ativo; e 9. Ao contar até oito, o prescaler incrementa o registrador do temporizador. 1 2 3 4 5 6 Figura 36. Diagrama de formas de onda da simulação da execução da aplicação Exemplo 5 Parte-2 A Figura 36 apresenta um segundo trecho da simulação do exemplo prático. Na figura, destacam-se os seguintes eventos: 1. O estouro do temporizador gera uma interrupção; 2. O controlador de interrupção identifica a interrupção gerada pelo temporizador como válida e acrescenta no registrador interrupções pendentes25 (IPR, Interrupt Pending Register) e ativa (=1) o bit correspondente (bit 0) no registrador int_status e gera uma interrupção para a CPU; 25 Registrador interno do bloco do temporizador que contém o resultado da função: int_status AND int_config, ou seja, contem as interrupções que foram solicitadas e que estão ativas. Este registrador não está visível ao programador. 77 3. Após receber a interrupção do controlador de interrupção, a CPU transfere o PC para o endereço de tratamento de interrupções (0x0001); 4. A flag de interrupção (int_stauts) gerada pelo temporizador é limpa via software; 5. O contador do temporizador é inicializado com uma constante permitindo gerar intervalos com mais precisão; 6. Após a instrução RETINT, a CPU continua seu processamento a partir do ponto de parada. As validações por diagrama de forma de ondas foram realizadas no simulador interno do Quartus-II® utilizando como dispositivo de FPGA o modelo EPF10K70RC240-4 da família FLEX10K. A escolha por este dispositivo deve-se ao fato da prototipação (etapa seguinte à validação) ter sido realizada nesse modelo. A Tabela 10 apresenta o custo de área em FPGA para as aplicações utilizadas no processo de validação. A variação do custo de células lógicas deve-se ao tamanho do programa alocado na memória de programa (ROM) e dos recursos utilizados por este. O fato do Exemplo 5 ser o que obteve maior consumo já era esperado, pois este é o que possui maior quantidade de linhas de programa além de utilizar todos os recursos do µBIP. Para o modelo de FPGA utilizado nesse projeto, o menor testbench, cast, utilizou aproximadamente 13% da área de células lógicas disponíveis, já o maior testbench, Exemplo 5, utilizou aproximadamente 34%. Tabela 10. Custo das Aplicações na FPGA FLEX10K-EPF10K70RC240-4 Aplicação Células Lógicas Flip-flops LUTs LUTs/Flipflops Bits de Memória cast 492 47 386 59 16384 divmul fib gcd int2bin negcnt sort sqroot xram Exemplo 5 1055 992 805 686 513 1050 996 934 1264 57 59 46 41 50 58 58 55 55 821 769 616 537 408 816 773 722 1019 177 164 143 108 55 176 165 157 190 16384 16384 16384 16384 16384 16384 16384 16384 16384 A Figura 37 apresenta o custo por bloco para a aplicação Exemplo 5 – Timer Simplificado. Na figura é apresentado um comparativo com duas implementações distintas do bloco ROM: (i) 78 ROM em células lógicas, utilizando constantes; e (ii) ROM em bits de memória (uma área exclusiva da FPGA) utilizando um modelo de memória próprio para a FPGA. Como a FPGA utilizada no exemplo não possui uma área de “bits de memória” capaz de comportar as memórias de dados e instruções, este espaço foi dividido entre as duas. Devido ao fato da organização do µBIP ser monocíclico, quando o sistema é compilado utilizando ROM em células lógicas, o compilador é capaz de reconhecer quais recursos do µBIP estão sendo utilizados pelo programa armazenado na ROM e otimizar o hardware para isso. Já quando o sistema utiliza ROM em bits de memória a quantidade de células lógicas utilizadas por cada bloco se mantém. Assim, se comparado a Tabela 10 é possível notar que em alguns testbenchs é vantajosa a utilização de ROM em células lógicas, como por exemplo, o testbench cast que utiliza poucos recursos. Na figura também é possível notar que em relação a ROM em células lógicas, o bloco que CPU é responsável por mais de 45% de toda a área ocupada, porém do restante, 689 células lógicas, aproximadamente 44% são referentes ao bloco de memória ROM onde está o programa. Bloco + ubip + cpu + control - stack + datapath - functionunit - ram - rom + io_port0 + io_port1 - timer - interruptcontroller - detector_edge - databus - frequencydivider ROM em ROM em Células Lógicas Bits de Memória Células Bits de Células Bits de Lógicas Memória Lógicas Memória 1264 0 971 0 575 0 589 0 231 0 246 0 167 0 162 0 344 0 343 0 253 0 253 0 0 16384 0 8192 302 0 0 8192 52 0 54 0 53 0 53 0 64 0 49 0 43 0 44 0 6 0 6 0 133 0 142 0 4 0 4 0 Figura 37. Custo por bloco da aplicação Exemplo 5 A Tabela 11 apresenta uma análise de período de clock e freqüência máxima para as aplicações utilizadas na validação do modelo. Em resumo, o modelo possui um período de clock médio de 146,120 ns e uma freqüência média de 6,873 MHz. Lembra-se que a variação do clock e 79 freqüência é determinada pela forma como foi implementado o modelo e que nesse trabalho não foram realizados nenhuma otimização massiva nesse sentido. Tabela 11. Análise de tempo na FPGA FLEX10K-EPF10K70RC240-4 Aplicação Período do clock (ns) Freqüência (MHz) cast 134,400 7,44 divmul fib 148,200 143,800 6,75 6,95 gcd int2bin 148,200 148,000 6,75 6,76 negcnt 125,400 7,97 sort sqroot xram Exemplo 5 152,000 153,600 148,400 159.200 6,58 6,51 6,74 6.28 80 3.5.2 Prototipação Física A prototipação física do modelo foi realizada utilizando o kit de prototipação UP-2 da fabricante ALTERA® (Figura 38). Essa placa possui duas FPGA: (i) FLEX®10K: EPF10K70RC240-4; e (ii) MAX®7000: EPM7128SLC84-7. Para a prototipação utilizou-se a FPGA FLEX®10K nessa FPGA estão associados um dual-display de 7-segmentos, um seletor de 8 pinos, dois botões Push-Button e um oscilador de 25.175MHz. Maiores informações sobre o kit utilizado estão disponíveis em ALTERA CORPORATION(2008). A aplicação onde os resultados da prototipação são visíveis é o Exemplo 5- Timer Simplificado de Souza(2004) principalmente por tratar de um exemplo típico de uso de microcontroladores. Para esta aplicação foram utilizados: (i) display de 7-segmentos para mostrar o contador; (i) dois botões para ativar e paralisar o timer; e (iii) um dos seletores para o botão de reset. A configuração dos pinos para essa aplicação é apresentada na Tabela 12. Como mostra a tabela, o µBIP utiliza 34 pinos sendo 32 deles para portas de E/S, um para o clock e outro para o reset. Figura 38. Kit de prototipação Altera® UP-2 Os resultados obtidos com a prototipação foram satisfatórios e confirmaram o funcionamento do µBIP implementado nesse trabalho em um protótipo físico. Porém, não pode-se considerar que o modelo tenha sido validado exaustivamente. Para isso seria necessário uma carga 81 horária maior destinada essa etapa. Pretende-se seguir realizando testes no protótipo físico durante o mês de julho, a fim de confirmar ainda mais seu correto funcionamento. Tabela 12. Configuração de pinagem para prototipação no kit UP-2 µBIP UP-2 µBIP UP-2 port0_data[15] port1_data[15] PIN_21 port0_data[14] port0_data[13] port0_data[12] port0_data[11] port0_data[10] port0_data[9] port0_data[8] port0_data[7] port0_data[6] port0_data[5] port0_data[4] port0_data[3] port0_data[2] port0_data[1] port0_data[0] rst port1_data[14] port1_data[13] port1_data[12] port1_data[11] port1_data[10] port1_data[9] port1_data[8] port1_data[7] port1_data[6] port1_data[5] port1_data[4] port1_data[3] port1_data[2] port1_data[1] port1_data[0] clk PIN_20 PIN_19 PIN_25 PIN_18 PIN_17 PIN_23 PIN_24 PIN_11 PIN_09 PIN_08 PIN_14 PIN_07 PIN_06 PIN_12 PIN_13 PIN_91 PIN_29 PIN_28 PIN_41 82 4 CONCLUSÕES Neste trabalho foram apresentados o projeto e a implementação de um microcontrolador básico planejado para uso em disciplinas introdutórias de programação de microcontroladores e relacionadas ao projeto de sistemas digitais. Os resultados produzidos por esse trabalho foram: (i) a especificação conceitual da arquitetura e organização de um microcontrolador com recursos reduzidos; (ii) a criação de ferramentas de software (montador, ligador e simulador ISA) para o microcontrolador produzido; (iii) a especificação em linguagem VHDL do microcontrolador; e (iv) a síntese para FPGAs da Altera®. Foram apresentados, também, uma revisão de conceitos base para a realização do projeto. Foram feitos estudos teóricos sobre sistemas embarcados, arquitetura e organização de computadores e microcontroladores, assim como estudos teórico-práticos sobre o uso do ArchC e a modelagem do processador BIP II. Destaca-se que foram encontradas algumas dificuldades relacionadas à instalação e uso do ArchC devido a divergências de informações na documentação associada. Essas dificuldades foram contornadas e as soluções encontradas foram registradas no guia de instalação e uso disponibilizado no Apêndice D , onde é possível observar os passos realizados para instalação do ArchC e de suas ferramentas de apoio, bem como os passos necessários para a geração de um simulador e montador para uma dada arquitetura. Destaca-se que foi apresentado e publicado nos anais do SIM 2008 (23th South Symposium on Microelectronics) um artigo com o resumo desse trabalho e com os resultados alcançados com o ArchC (PEREIRA; ZEFERINO, 2008). Outros dois artigos foram submetidos a dois eventos: (i) CLEI 2008 – Conferência Latino-americana de Informática, Santa Fé – Argentina; e (ii) VIII SFORUM, Gramado, RS – Brasil. Entende-se que a relevância deste projeto está nos resultados obtidos, disponibilizando uma arquitetura de microcontrolador pensada para facilitar o aprendizado da programação e da implementação de microcontroladores. Além disso, busca-se promover uma maior integração entre as disciplinas permitindo que os processadores da família BIP possam ser usados em diferentes fases e disciplinas de cursos de graduação e de pós-graduação. Entende-se, também, que este trabalho propiciou a este aluno a integração e consolidação de conceitos estudados ao longo da graduação e, também, o aprendizado de novos conceitos e tecnologias. Por fim, destaca-se que os objetivos definidos para esse trabalho foram alcançados e relatados nesse documento. 4.1 TRABALHOS FUTUROS No desenvolvimento deste trabalho foram identificadas diversas oportunidades de trabalhos co-relacionados a este e que dão continuidade a este projeto. Sendo: • Compilador C: criação de um compilador da linguagem C para o assembly do µBIP; • IDE de desenvolvimento: desenvolvimento de uma IDE que integre todas as ferramentas geradas facilitando a utilização dessas pelos usuários; e • Inclusão de novos periféricos; • Sistema Operacional: implementação de um sistema operacional para o µBIP. • Implementação do modelo em ASIC: implementação do modelo de microcontrolador desenvolvido neste trabalho em um ASIC; 84 REFERÊNCIAS BIBLIOGRÁFICAS ALTERA CORPORATION. University Program UP2 Education Kit User Guide. 2004. Disponível em: <http://www.altera.com/literature/univ/upds.pdf> Acesso em: maio/2008. BALDASSIN, Alexandro. Geração automática de montadores em ArchC. 2005. Dissertação (Mestrado em Ciência da Computação)-Programa de Pós-Graduação em Ciência da Computação, Universidade Estadual de Campinas, Campinas, 2005. BRITO, Alírio C. de. Considerações sobre a utilização de microcircuitos eletrônicos encapsulados em plástico nas aplicações de alta confiabilidade. 2003. Monografia (Especialização em Engenharia da Qualidade)–Escola Politécnica, Universidade de São Paulo, São Paulo, 2003. BROWN, Stephen; VRANESIC, Zvonko. Fundamentals of Digital Logic with VHDL Design. New York: McGraw Hill. 2000. CARRO, Luigi;WAGNER, Flávio R. Sistemas computacionais embarcados. In: XXII JORNADAS DE ATUALIZAÇÃO EM INFORMÁTICA, 2003. (Capítulo 2). CARTER, Nicholas P. Teoria e problemas de arquitetura de computadores. Porto Alegre: Bookman, 2003. D’AMORE, Roberto. VHDL: descrição e síntese de circuitos digitais. Rio de Janeiro: LTC, 2005. FREESCALE SEMICONDUCTOR INC. M68HC08 microcontrollers. Arizona: Freescale, 2004. GÜNTZEL, José L. Estilos de projeto. In: REIS, Ricardo A. da L (Org.). Concepção de circuitos integrados. 2. ed. Porto Alegre: Instituto de Informática da UFRGS: Sagra Luzzatto, 2002. (Capítulo 5). GUPTA, Rajesh K.; ZORIAN, Yervant. Introducing Core-Based System Design. IEEE Design & Test of Computers, v. 14, n. 4, p. 15-25, dez 1997. HENNESSY, John L.; PATTERSON, David A. Arquitetura de computadores: uma abordagem quantitativa. Rio de Janeiro: Campus, 2003. HENZINGER, Thomas A; SIFAKIS, Joseph. The Discipline of Embedded Systems Design. Computer. v. 40, n.10, p. 32-40. out. 2007. INTEL. 8-Bit Embedded Controllers. Arizona, 1991. MARINHO, José E. S; MARINHO, Ednaldo S. Mini-curso de microcontrolador. Saber Eletrônica n° 2, jan. de 2001. MATIC, Nebojsa. PIC Microcontrollers. 2000. Disponível em: <http://www.mikroe.com/en/books/picbook/0_Uvod.htm> Acesso em: 30 set 2007. MELO, Paulo R. de S.; RIOS, Evaristo C. S. D.; GUTIERREZ, R. M. V. Componentes eletrônicos: perspectivas para o Brasil. BNDES Setorial, Rio de Janeiro, n. 13, p. 3-64, 2001. 85 MENDONÇA, Alexandre; ZELENOVSKY, Ricardo. Eletrônica digital: curso prático e exercícios. Rio de Janeiro: MZ, 2004. MICROCHIP. PIC16F62X Data Sheet: FLASH-Based 8-Bit CMOS Microcontroller. Arizona, 2003. MICROCHIP. PIC16F87X Data Sheet: 28/40-Pin 8-Bit CMOS FLASH microcontrollers. Arizona, 2001. MICROCHIP. PIC18FXX2 Data Sheet: high performance, enhanced FLASH microcontroller with 10-Bit A/D. Arizona, 2002. MORANDI, Diana ; PEREIRA, Maicon Carlos ; RAABE, André Luis Alice ; ZEFERINO, Cesar Albenes . Um processador básico para o ensino de conceitos de arquitetura e organização de computadores. Hífen, Uruguaiana, v. 30, p. 73-80, 2006. MORANDI, Diana ; RAABE, André Luis Alice ; ZEFERINO, Cesar Albenes. Processadores para Ensino de Conceitos Básicos de Arquitetura de Computadores. In: WORKSHOP DE EDUCAÇÃO EM ARQUITETURA DE COMPUTADORES, 1., 2006, Ouro Preto. Proceedings of the 18th International Symposium on Computer Architecture and High Performance Computing Workshops. Porto Alegre : SBC, 2006. p. 17-24. PATTERSON, David A; HENNESSY, John L. Organização e projeto de computadores: a interface hardware/software. 2. ed. Rio de Janeiro: LTC, 2000. PEREIRA, Maicon Carlos; ZEFERINO, Cesar Albenes. Architectural Specification of a Microcontroller by Using ArchC in: 23th South Symposium on Microelectronics – SIM2008, 2008. Bento Gonçalves. SIM 2008 Proceedings, 2008. PREDKO, Michael. Handbook of microcontrollers. New York: McGraw-Hill, 1998. RABBIT SEMICONDUCTOR. Rabbit 3000® Microprocessor User’s Manual. Califórnia, 2007. REIS, André. Síntese lógica. In: REIS, Ricardo A. da L (Org.). Concepção de Circuitos Integrados, 2. ed. Porto Alegre: Instituto de Informática da UFRGS: Sagra Luzzatto: 2002. (Capítulo 7). SHIVA, Sajjan G. Computer design and architecture. 3. ed. [S.l.]: Marcel: 2000. SOUZA, Antonio H. de; NOVELETTO, Fabrício. Considerações sobre os microcontroladores. Disponível em: <http://www2.joinville.udesc.br/~esp7labmic/Material_HC08/artigo.doc> Acesso em: 20 set 2007. SOUZA, José de S. Desbravando o PIC: ampliado e atualizado para PIC16F628A. 7 ed. São Paulo: Erica, 2004. STALLINGS, William. Arquitetura e organização de computadores: projeto para o desempenho. 5. ed. São Paulo: Prentice Hall, 2002. THE ARCHC TEAM. The ArchC architecture description language v2.0: reference manual. Campinas: The ArchC Team, 2007. 86 THE ARCHC TEAM. The ArchC project home page. Disponível em: < http://www.archc.org >. Acesso em: 15 out 2007a. THE DALTON PROJECT TEAM. The UCR Dalton Project. University of California – Riverside, 2001. Disponível em: < http://www.cs.ucr.edu/~dalton/ >. UYEMURA, John P. Sistemas digitais: uma abordagem integra. São Paulo: Pioneira Thomson Learning, 2002. VAHID, Frank, GIVARGIS, Tony, Embedded sytem design: a unified hardware/software introduction. [S.l.]: John Wiley & Sons, Inc., 2002. VAHID, Frank, GIVARGIS, Tony. Platform tuning for embedded systems design. IEEE Computer, v. 34, n. 3, p. 112-114, mar 2001 WEBER, Raul F. Fundamentos de arquitetura de computadores. 2. ed. Porto Alegre: Sagra– Luzzatto, 2004. WOLF, Wayne. What is embedded computing? IEEE Computer, v. 35, n.1, p.136-137, jan 2002. ZEFERINO, Cesar A. Especificação da Arquitetura e da Organização do Processador BIP. Itajaí, 2007. (Relatório Técnico). 87 APÊNDICES A DESCRIÇÃO DO PROCESSADOR BIP-II EM ARCHC Este apêndice apresenta os códigos da implementação funcional do processador BIP-II na linguagem ARCHC realizada durante o projeto deste trabalho. As subseções a seguir apresentam os arquivos de tais descrições. A.1 RECURSOS DA ARQUITETURA AC_ARCH(bip2){ ac_mem memRAM:2K; ac_mem memROM:64k; ac_reg ACC; ac_reg Z, N; ac_wordsize 16; ARCH_CTOR(bip2) { ac_isa("bip2_isa.ac"); set_endian("big"); }; }; A.2 CONJUNTO DE INSTRUÇÕES AC_ISA(bip2){ ac_format Type_I ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> ac_instr<Type_I> = "%op:5 %operand:11"; add, sub, addi, subi; sto,ld,ldi; hlt; beq, bne, bgt, bge, blt, ble; jmp; ISA_CTOR(bip2){ hlt.set_asm("hlt %imm", operand); hlt.set_decoder(op=0x00); sto.set_asm("sto %imm", operand); sto.set_decoder(op=0x01); ld.set_asm("ld %imm", operand); ld.set_decoder(op=0x02); ldi.set_asm("ldi %imm", operand); ldi.set_decoder(op=0x03); add.set_asm("add %imm", operand); add.set_decoder(op=0x04); addi.set_asm("addi %imm", operand); addi.set_decoder(op=0x05); sub.set_asm("sub %imm", operand); sub.set_decoder(op=0x06); subi.set_asm("subi %imm", operand); subi.set_decoder(op=0x07); beq.set_asm("beq %imm", operand); beq.set_decoder(op=0x08); bne.set_asm("bne %imm", operand); bne.set_decoder(op=0x09); bgt.set_asm("bgt %imm", operand); bgt.set_decoder(op=0x0A); bge.set_asm("bge %imm", operand); bge.set_decoder(op=0x0B); blt.set_asm("blt %imm", operand); blt.set_decoder(op=0x0C); ble.set_asm("ble %imm", operand); ble.set_decoder(op=0x0D); jmp.set_asm("jmp %imm", operand); jmp.set_decoder(op=0x0E); }; }; A.3 COMPORTAMENTO DAS INSTRUÇÕES #include #include #include #include #include #include #include "bip2_isa.H" "bip2_isa_init.cpp" "bip2_bhv_macros.H" <stdio.h> <math.h> <stdarg.h> <systemc.h> //!'using namespace' statement to allow access to all bip2-specific datatypes using namespace bip2_parms; //!Behavior executed before simulation begins. void ac_behavior( begin ){ printf("-- Inicio da Simulacao --\n"); for (unsigned int i=0; i< 20;i++) memRAM.write(i, 0); }; //!Behavior executed after simulation ends. void ac_behavior( end ){ printf("-- Fim da Simulacao --\n"); printf("-- Resultado da memRAMoria --\n"); //for (int i=0; i<pow(memRAM.get_size(),2);i++) for (int i=0; i<30;i++) { printf(" memRAM[%d]=0x%x", i, memRAM.read(i)); if (i%5==0) printf("\n"); } printf("\n"); }; 90 //!Generic instruction behavior method. void ac_behavior( instruction ){ ac_pc = ac_pc + 2; }; //! Instruction Format behavior methods. void ac_behavior( Type_I ){ //Atualiza o Status //----------------------------if (ACC.read()==0) Z.write(1); else Z.write(0); if (ACC.read()<0) N.write(1); else N.write(0); //--------------------------------printf("-----------------------------------------------\n"); printf("PC= 0x%x ACC = 0x%x Z=0x%x N=0x%x\n", ac_pc-2, ACC.read(), Z.read(), N.read()); } //!Instruction add behavior method. void ac_behavior( add ){ printf("ADD 0x%x + 0x%x\n", ACC.read(), memRAM.read(operand) ); ACC.write(ACC.read()+(memRAM.read(operand)&0xFFFF)); } //!Instruction sub behavior method. void ac_behavior( sub ){ printf("SUB 0x%x + 0x%x\n", ACC.read(), memRAM.read(operand) ); ACC.write(ACC.read()-(memRAM.read(operand)&0xFFFF)); } //!Instruction addi behavior method. void ac_behavior( addi ){ printf("ADDI 0x%x + 0x%x\n", ACC.read(), operand ); ACC.write(ACC.read()+operand); } //!Instruction subi behavior method. void ac_behavior( subi ){ printf("SUBI 0x%x + 0x%x\n", ACC.read(), operand ); ACC.write(ACC.read()-operand); } //!Instruction sto behavior method. void ac_behavior( sto ){ printf("STO 0x%x IN 0x%x\n", ACC.read(), operand ); memRAM.write(operand, ACC.read()); printf("memRAM[%d] = 0x%x\n",(int)operand,memRAM.read(operand)); } //!Instruction ld behavior method. void ac_behavior( ld ){ printf("LD memRAM[%d] = 0x%x\n", (int)operand, memRAM.read(operand) ); ACC.write(memRAM.read(operand)); } 91 //!Instruction ldi behavior method. void ac_behavior( ldi ){ printf("LDI 0x%x\n", operand ); ACC.write(operand); } //!Instruction hlt behavior method. void ac_behavior( hlt ){ printf("HLT\n"); } //!Instruction beq behavior method. void ac_behavior( beq ){ printf("BEQ 0x%x\n", operand ); if (Z.read()==1) { ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction bne behavior method. void ac_behavior( bne ){ printf("BNE 0x%x\n", operand ); if (Z.read()==0) { ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction bgt behavior method. void ac_behavior( bgt ){ printf("BGT 0x%x\n", operand ); if ((N.read()==0)&&(Z.read()==0)) { ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction bge behavior method. void ac_behavior( bge ){ printf("BGE 0x%x\n", operand ); if (N.read()==0) { ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction blt behavior method. void ac_behavior( blt ){ printf("BLT 0x%x\n", operand ); if (N.read()==1) { 92 ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction ble behavior method. void ac_behavior( ble ){ printf("BLE 0x%x\n", operand ); if ((N.read()==1)&&(Z.read()==1)) { ac_pc = operand; printf("go to 0x%x\n",operand); }else { printf("continue.\n"); } } //!Instruction jmp behavior method. void ac_behavior( jmp ){ printf("JMP 0x%x\n", operand ); ac_pc = operand; printf("go to 0x%x\n",operand); } 93 B QUESTIONÁRIO Este apêndice apresenta a pesquisa feita a professores, engenheiros e profissionais da área sobre características básicas de um microcontrolador visando sua aplicação no âmbito educacional. A seção mostra a carta de apresentação juntamente com o questionário enviado aos avaliadores. Já a seção mostra o resultado da pesquisa. B.1. CARTA DE APRESENTAÇÃO Prezado(a) Sr(a), Estamos realizando o projeto de uma arquitetura de microcontrolador para fins didáticos, visando disponibilizá-la para uso no ensino em diversas disciplinas, incluindo: Programação, Arquitetura de Computadores, Compiladores, Projeto de Sistemas Digitais, Microcontroladores, entre outras. O microcontrolador será baseado em uma arquitetura de processador denominada BIP Basic Instruction-set Processor, desenvolvida na UNIVALI. Como premissa, o BIP busca ser simples o suficiente para que um aluno iniciante em Computação aprenda rapidamente a programálo na sua linguagem de montagem, e também que um aluno com conhecimentos de circuitos digitais e de uma linguagem de descrição de hardware consiga modelá-lo e prototipá-lo em FPGA. O microcontrolador proposto será denominado uBIP (micro BIP) e deverá ter o mesmo foco do BIP: facilitar o aprendizado de conceitos básicos de programação e de projeto, considerando as aplicações básicas mais comuns de microcontroladores. A sua primeira versão será desenvolvida no 1o semestre de 2008, por um aluno de TCC do Curso de Ciência da Computação da UNIVALI, que utilizará ferramentas e tecnologias como ArchC (www.archc.org), VHDL e FPGA. Inicialmente, será feita a especificação da arquitetura do microcontrolador, que será modelada no ArchC. Essa ferramenta será usada para gerar um simulador de conjunto de instruções, um montador e um ligador para o uBIP. Após, será feito o projeto de sua organização, a qual será modelada em VHDL e prototipada em FPGA. Aplicativos de teste serão codificados em assembly e usados para validar o protótipo físico usando kits de desenvolvimento para FPGA da Altera. Estamos entrando em contato com professores e profissionais experientes no ensino e no uso de microcontroladores para identificar características mínimas para o uBIP. Agradecemos se puder colaborar com essa pesquisa respondendo às perguntas abaixo, o que deverá lhe consumir poucos minutos. Pedimos que, ao responder, considere as aplicações tipicamente utilizadas nas fases iniciais de aprendizagem de microcontroladores, identificando os requisitos de software e de hardware dessas aplicações. Por favor, envie suas respostas a [email protected] ou realizando um reply a esta mensagem. Desde já agradecemos a sua ajuda. Cordialmente, Cesar Zeferino PS: Se possível, agradecemos o reencaminhamento desta mensagem a conhecidos que possam colaborar neste projeto. Questionário de Levantamento de Requisitos para o µBIP IDENTIFICAÇÃO Nome: _______________________________________ Universidade/Empresa: _______________________________________ Cargo/Função: _______________________________________ Tempo de experiência no ensino/projeto baseado em microcontroladores: _____ QUESTIONÁRIO 1. Além das instruções aritméticas, de transferência com a memória e de desvio condicional e incondicional (já disponíveis no BIP), que classes de instrução você considera mais relevantes para a construção de aplicações básicas (o conjunto de instruções uBIP terá no máximo 32 instruções)? - Lógica booleana: ( ) Sim ( ) Não - Deslocamento lógico: ( ) Sim ( ) Não - Deslocamento aritmético: ( ) Sim ( ) Não 95 - Manipulação e teste de bit: ( ) Sim ( ) Não - Ativação de modo sleep: ( ) Sim ( ) Não - Outras, indique: 2. Que periféricos você acha que seriam necessário para um microcontrolador mínimo? - Pinos de E/S unidirecionais: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos pinos:____ - Pinos de E/S bidirecionais: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos pinos: ____ - Pinos de interrupção sensível à borda: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos pinos: ____ - Pinos de interrupção sensível ao nível: ( )Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos pinos: ____ - Temporizador programável: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos bits: ____ - Contador de pulsos: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos bits: ____ - Temporizador Watchdog: ( )Sim ( ) Não Se sua resposta tiver sido Sim, indique o intervalo mínimo de estouro: ____ 96 - Prescaler para os temporizadores: ( ) Sim ( ) Não - Conversor A/D: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique quantos bits: ____ - Porta de comunicação serial: ( ) Sim ( ) Não Se sua resposta tiver sido Sim, indique qual tipo (ex. UART, I2C): - Outros. Indique: 3. Considerando o objetivo do microcontrolador proposto, qual a sua opinião sobre a inclusão de suporte a chamada de procedimentos (pilha e instruções do tipo call e return)? ( ) Essencial ( ) Importante, mas não essencial ( ) Dispensável para aplicações básicas ( ) Irrelevante 4. Sugestões/comentários: 97 B.2. TABULAÇÃO DOS RESULTADOS A Tabela 13 apresenta o resultado da coleta dos dados realizada com o questionário apresentado anteriormente. A coluna “sim” mostra a quantidade de amostras que responderam “sim”. A coluna “não” apresenta a quantidade de respostas “não”. A coluna Opc apresenta a opção mais escolhida e a coluna “%” apresenta a porcentagem favorável ao item em questão. No item “Com.Serial?” as respostas do tipo de comunicação serial (1-UART 2-I2C 5-SPI) são somatórias, assim uma resposta 6 significa que o pesquisado escolheu por UART e SPI. Tabela 13. Tabulação dos Dados Coletados Sim Não Opc Classes de Instruções Logica Booleana Deslocamento Lógico Deslocamento Aritmético Manipulação de bit Ativação do modo sleep Outras Periféricos E/S Unidirecionais? Qtd E/S Unidirecionais E/S bidirecionais? Qtd E/S bidirecionais Interrupção Borda? Qtd Interrupção Interrupção Nivel? Qtd Interrupção Temporizador? Qtd bits temporizador Contador de Pulsos? Qtd bits contador Watchdog? Tempo estouro Prescaler? Conversor A/D? Qtd bits Com. Serial? 1-UART 2-I2C 5-SPI Chamada de Procedimento Opniao: (1-4) % Q1 Q2 Q3 Q4 Q5 Q6 Q7 9 7 3 7 1 0 2 6 2 8 100% 78% 33% 78% 11% S N N S N 5 4 56% 60% 78% 8 43% 78% 1 57% 56% 1 60% 100% 16 33% 33% 16 33% 33% 1ms 67% 56% 56% 8 40% 78% N 8 7 2 7 2 5 4 9 0 3 6 3 6 5 5 4 4 7 2 1 67% 98 S S N S S Q8 Q9 S S S S N S S N N N S S N N N S S S S N S S N S N S S S S N S N N S N S S 8 8 S S S 10 16 8 S S N ? 2 N N S 2 S S S 3 13 16 N S S 13 32 N N N N S 8 N N N S 4 S 4 S 2 S 2 S 8 N S 4 N 1 2 1 1 N S 4 N N S 8 S 1 S S S 16 8 8 S N S S S 1 1 1 1 N S S S N 1 1 1 S S S S S 8 16 16 ? 8 N N S N N 16 N N S S S N 1s 1ms 1ms S N N S S S S N N S S S N N 12 8 12 S N S S S S S ? 1 3 6 1 3 2 1 1 2 1 C CONJUNTO DE INSTRUÇÕES DO µBIP Este apêndice apresenta uma descrição mais detalhada do conjunto de instrução do µBIP. As subseções o conjunto de instruções de cada classe de instrução. C.1. CLASSE: CONTROLE Halts HLT Sintaxe: HLT Descrição: Desabilita a atualização do PC Opcode: 00000 Status: Nenhum bit afetado PC: Não é atualizado Operação: Nenhuma operação é realizada Exemplo: HLT Antes da instrução: PC = 0x0100 Após a instrução: PC = 0x0100 C.2. CLASSE: ARMAZENAMENTO Store STO Sintaxe: STO operand Descrição: Armazena o conteúdo do ACC em uma posição da memória indicada pelo operand. Opcode: 00001 Status: Nenhum bit afetado PC: PC ← PC + 1 Operação: Memory[operand] ← ACC Exemplo: STO 0x0002 Antes da instrução: ACC = 0x0005 MEM[2] = 0x0000 Após a instrução: ACC = 0x0005 MEM[2] = 0x0005 C.3. CLASSE: CARGA Load LD Sintaxe: LD operand Descrição: Carrega um valor armazenado em uma posição de memória indicado pelo operand para o registrador ACC . Opcode: 00010 Status: Nenhum bit afetado PC: PC ← PC + 1 Operação: ACC ← Memory[operand] Exemplo: LD 0x0002 Antes da instrução: ACC = 0x0000 MEM[2] = 0x0005 Após a instrução: ACC = 0x0005 MEM[2] = 0x0005 LDI Load Immediate Sintaxe: LDI Descrição: Carrega o valor de um operando imediato para o registrador ACC Opcode: 00011 Status: Nenhum bit afetado PC: PC ← PC + 1 Operação: ACC ← operand Exemplo: LDI 0x0005 operand Antes da instrução: ACC = 0x0000 Após a instrução: ACC = 0x0005 100 C.4. CLASSE: ARITMÉTICA ADD Sintaxe: ADD operand Descrição: O valor do registrador ACC é somado com o valor armazenado na posição de memória indicado pelo campo operand e o resultado armazenado no ACC . Opcode: 00100 Status: Z, N e C são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC + Memory[operand] Exemplo: ADD 0x0002 Antes da instrução: ACC = 0x0004 MEM[2] = 0x0003 Após a instrução: ACC = 0x0007 MEM[2] = 0x0003 ADDI Add Immediate Sintaxe: ADDI Descrição: O valor do registrador ACC é somado com o valor operando operand imediato e o resultado armazenado no ACC . Opcode: 00101 Status: Z, N e C são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC + operand Exemplo: ADDI 0x0002 Antes da instrução: ACC = 0x0004 Após a instrução: ACC = 0x0006 101 SUB Subtract Sintaxe: SUB Descrição: O valor do registrador ACC é subtraído pelo valor armazenado na operand posição de memória indicado pelo campo operand e o resultado armazenado no ACC . Opcode: 00110 Status: Z, N e C são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC - Memory[operand] Exemplo: SUB 0x0002 Antes da instrução: ACC = 0x0004 MEM[2] = 0x0003 Após a instrução: ACC = 0x0001 MEM[2] = 0x0003 SUBI Subtract Immediate Sintaxe: SUBI Descrição: O valor do registrador ACC é subtraído pelo valor do operando operand imediato e o resultado armazenado no ACC . Opcode: 00110 Status: Z, N e C são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC - operand Exemplo: SUBI 0x0002 Antes da instrução: ACC = 0x0004 Após a instrução: ACC = 0x0002 102 C.5. CLASSE: LÓGICA BOOLEANA NOT Sintaxe: NOT Descrição: Aplica o operador de “negação” lógico ao valor armazenado no ACC e armazena o resultado no ACC. Opcode: 01111 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← NOT (ACC) Exemplo: NOT Antes da instrução: ACC = 0x000F Após a instrução: ACC = 0xFFF0 AND Sintaxe: AND operand Descrição: Aplica o operador “E” lógico entre o valor do registrador ACC e o valor armazenado na posição de memória indicado pelo operand. O resultado é armazenado no ACC . Opcode: 10000 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC AND Memory[operand] Exemplo: AND 0x0002 Antes da instrução: ACC = 0x00C4 MEM[2] = 0x0007 Após a instrução: ACC = 0x0004 MEM[2] = 0x0007 103 ANDI And Immediate Sintaxe: ANDI Descrição: Aplica o operador “E” lógico entre o valor do registrador ACC e o operand valor do operando imediato. O resultado é armazenado no ACC . Opcode: 10001 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC AND operand Exemplo: ANDI 0x0003 Antes da instrução: ACC = 0x00C5 Após a instrução: ACC = 0x0001 OR Sintaxe: OR operand Descrição: Aplica o operador “OU” lógico entre o valor do registrador ACC e o valor armazenado na posição de memória indicado pelo operand. O resultado é armazenado no ACC . Opcode: 10010 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC OR Memory[operand] Exemplo: OR 0x0002 Antes da instrução: ACC = 0x0004 MEM[2] = 0x00C0 Após a instrução: ACC = 0x00C4 MEM[2] = 0x00C0 104 ORI Or Immediate Sintaxe: ORI Descrição: Aplica o operador “OU” lógico entre o valor do registrador ACC operand e o valor do operando imediato. O resultado é armazenado no ACC . Opcode: 10011 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC OR operand Exemplo: ORI 0x0002 Antes da instrução: ACC = 0x0004 Após a instrução: ACC = 0x0006 XOR Sintaxe: XOR operand Descrição: Aplica o operador “OU” lógico exclusivo entre o valor do registrador ACC e o valor armazenado na posição de memória indicado pelo operand. O resultado é armazenado no ACC . Opcode: 10100 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC XOR Memory[operand] Exemplo: XOR 0x0002 Antes da instrução: ACC = 0x0006 MEM[2] = 0x0004 Após a instrução: ACC = 0x0002 MEM[2] = 0x0004 105 XORI Xor Immediate Sintaxe: XORI Descrição: Aplica o operador “OU” lógico exclusivo entre o valor do operand registrador ACC e o valor do operando imediato. O resultado é armazenado no ACC . Opcode: 10101 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC XOR operand Exemplo: XORI 0x0002 Antes da instrução: ACC = 0x0006 Após a instrução: ACC = 0x0004 C.6. CLASSE: DESVIO Branch Equal BEQ Sintaxe: BEQ operand Descrição: Atualiza o valor do PC com o valor do campo operand caso o resultado da operação anterior na ULA foi zero. Opcode: 01000 Status: Nenhum bit é afetado PC: Se (STATUS.Z=1) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BEQ 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0005 STATUS.Z = 1 STATUS.N = 0 PC = 0x0002 106 BNE Branch Non-Equal Sintaxe: BNE Descrição: Atualiza o valor do PC com o valor do campo operand caso o operand resultado da operação anterior na ULA tenha sido diferente zero. Opcode: 01001 Status: Nenhum bit é afetado PC: Se (STATUS.Z=0) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BNE 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0006 STATUS.Z = 0 STATUS.N = 1 PC = 0x0002 BGT Branch Greater Than Sintaxe: BGT Descrição: Atualiza o valor do PC com o valor do campo operand caso o operand resultado da operação anterior na ULA tenha sido maior que zero. Opcode: 01010 Status: Nenhum bit é afetado PC: Se (STATUS.Z=0) e (STATUS.N=0) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BGT 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0004 STATUS.Z = 0 STATUS.N = 0 PC = 0x0002 107 BGE Branch Greater Equal Sintaxe: BGE Descrição: Atualiza o valor do PC com o valor do campo operand caso o operand resultado da operação anterior na ULA tenha sido maior ou igual zero. Opcode: 01011 Status: Nenhum bit é afetado PC: Se (STATUS.N=0) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BGE 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0005 STATUS.Z = 1 STATUS.N = 0 PC = 0x0002 BLT Branch Less Than Sintaxe: BLT Descrição: Atualiza o valor do PC com o valor do campo operand caso o operand resultado da operação anterior na ULA tenha sido menor que zero. Opcode: 01100 Status: Nenhum bit é afetado PC: Se (STATUS.N=1) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BLT 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0006 STATUS.Z = 0 STATUS.N = 1 PC = 0x0002 108 BLE Branch Greater Equal Sintaxe: BLE Descrição: Atualiza o valor do PC com o valor do campo operand caso o operand resultado da operação anterior na ULA tenha sido menor ou igual a zero. Opcode: 01101 Status: Nenhum bit é afetado PC: Se (STATUS.N=1) ou (STATUS.Z=1) então PC ← endereço Se não PC ← PC + 1 Operação: Nenhuma Operação Realizada Exemplo: LDI 0x0005 SUB 0x0008 BLE 0x0002 Antes da instrução: Após a instrução: PC = 0x000A MEM[8] = 0x0006 STATUS.Z = 0 STATUS.N = 1 PC = 0x0002 JMP Jump Sintaxe: JMP Descrição: Atualiza o valor do PC com o valor do campo operand, ou operand seja, realiza um desvio incondicional. Opcode: 01110 Status: Nenhum bit é afetado PC: PC ← endereço Operação: Nenhuma Operação Realizada Exemplo: JMP 0x0002 Antes da instrução: PC = 0x000A Após a instrução: PC = 0x0002 109 C.7. CLASSE: DESLOCAMENTO LÓGICO Shift Left Logical SLL Sintaxe: SLL operand Descrição: Realiza o deslocamento lógico à esquerda no número de bits informado pelo operand sobre o registrador ACC. Opcode: 10110 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC << operand Exemplo: SLL 0x0002 Antes da instrução: ACC = 0x0001 Após a instrução: ACC = 0x0004 SRL Shift Right Logical Sintaxe: SRL Descrição: Realiza o deslocamento lógico à direita no número de bits operand informado pelo operand sobre o registrador ACC. Opcode: 10111 Status: Z e N são afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← ACC >> operand Exemplo: SRL 0x0002 Antes da instrução: ACC = 0x0004 Após a instrução: ACC = 0x0001 110 C.8. CLASSE: MANIPULAÇÃO DE VETOR Load Vector LDV Sintaxe: LDV operand Descrição: Carrega o valor armazenado no endereço dado por (operand + INDR) para o registrador ACC. Opcode: 11000 Status: Não afetados por esta operação PC: PC ← PC + 1 Operação: ACC ← Memory[Operand + INDR] Exemplo: LDI 0x0001 STO $indr LDV $0 Antes da instrução: ACC = 0x0000 MEM[0]=0x0004 MEM[1]=0x0007 Após a instrução: ACC = 0x0007 MEM[0]=0x0004 MEM[1]=0x0007 STOV Store Vector Sintaxe: STOV operand Descrição: Armazena o valor do registrador ACC, no endereço dado por (operand + INDR). Opcode: 11001 Status: Não afetados por esta operação PC: PC ← PC + 1 Operação: Memory[operand + INDR] = ACC Exemplo: LDI 0x0001 STO $indr LDI 0x0003 LDV $0 Antes da instrução: ACC = 0x0000 MEM[0]=0x0004 MEM[1]=0x0007 Após a instrução: ACC = 0x0007 MEM[1]=0x0003 111 MEM[0]=0x0004 C.9. CLASSE: SUPORTE A PROCEDIMENTOS CALL Sintaxe: CALL operand Descrição: Realiza uma chamada de procedimento para o endereço de memória de instrução indicado pelo campo operand. Antes da chamada, o endereço de retorno (PC + 1) é armazenado na pilha (ToS). Opcode: 11100 Status: Não afetados por esta operação PC: ToS ← PC+1 PC ← operand Operação: Nenhuma operação realizada Exemplo: CALL 0x00F0 Antes da instrução: PC = 0x00D3 ToS = 0xXXXX Após a instrução: PC = 0x00F0 ToS = 0x00D4 RETURN Return Sintaxe: RETURN Descrição: Retorna da sub-rotina, recuperando o valor do PC armazenado na pilha (ToS). O procedimento chamado deve usar o ACC para retornar um valor ao procedimento chamador. Opcode: 11010 Status: Não afetados por esta operação PC: PC ← ToS Operação: Nenhuma operação realizada Exemplo: RETURN Antes da instrução:PC=0x00F0 ToS=0x00D3 ACC=Valor de Retorno Após a instrução: PC=0x00D3 ToS=0xXXXX ACC=Valor de Retorno RETINT Return Interrupt Sintaxe: RETINT Descrição: Retorna de uma interrupção para o endereço do programa antes da interrupção e habilita a interrupção geral. Opcode: 11011 Status: Não afetados por esta operação PC: PC ← ToS Operação: Nenhuma operação realizada Exemplo: RETINT Antes da instrução: PC = 0x00F0 ToS = 0x00D3 Após a instrução: PC = 0x00D3 ToS = 0xXXXX 113 D INSTALAÇÃO DO ARCHC Esse apêndice apresenta os passos realizados para instalação e configuração do ArchC utilizando o sistema operacional Ubuntu 7 e também testado no Kubuntu 7. As subseções deste apêndice são seqüenciais, assim, para realizar um procedimento da Subseção D.2., deve-se realizar primeiro a D.1. Os links indicados neste apêndice foram acessados em 10 outubro de 2007 e consideram as versões disponíveis na data ou versões compatíveis como o caso do pacote Binutils. D.1. OBTENDO OS ARQUIVOS DE INSTALAÇÃO 1. Criar a seguinte arvore de diretório: /home/myuser/files 2. Baixar o ArchC 2.0: <http://downloads.sourceforge.net/archc/archc-2.0.tar.gz> 3. Descompactar o pacote ArchC em: /home/myuser/files/archc2 4. Baixar o SystemC 2.2.0: <http://www.systemc.org > 5. Descompactar o pacote SystemC em: /home/myuser/files/systemc 6. Baixar o TLM 1.0: < http://www.systemc.org > 7. Descompactar o pacote TLM em: /home/myusers/files/tlm 8. Baixar o pacote Binutils 2.16.1: < http://ftp.gnu.org/gnu/binutils/binutils-2.16.1.tar.gz > 9. Descompactar o pacote Binutils em: /home/myusers/files/binutils 10. Baixar o pacote GDB 6.7.: < http://ftp.gnu.org/gnu/gdb/gdb-6.7.tar.gz > 11. Descompactar o pacote GDB em: /home/myusers/files/gdb 12. Baixar o modelo exemplo <http://downloads.sourceforge.net/archc/mips1-v0.7.8.tgz> 13. Descompactar o MIPS em: /home/myusers/files/mips MIPS-I em: 14. Baixar o Benchmark JPEG para o MIPS-I em: <http://143.106.24.201/%7Earchc/files/benchmarks/bin/mips1/mediabench/jpegmips1.tgz> 15. Descompactar em: /home/myusers/files/mips/jpeg D.2. INSTALAR O SYSTEMC Os comandos a seguir são realizados no terminal: 1. Criar diretório para o SystemC: mkdir /usr/local/systemc/ 2. Acessar o pacote do SystemC: cd /home/myuser/files/systemc 3. Criar diretório de instalação: mkdir /home/myuser/files/systemc/objdir/ 4. Acessar diretório de instalação: cd /home/myuser/files/systemc/objdir/ 5. Configurar a instalação: ../configure --prefix=/usr/local/systemc --with-systemc= /home/myuser/files/systemc 6. Instalando, utilizar usuário root para os comandos a seguir: make make install make check Maiores informações sobre a instalação do SystemC, consultar manual no site < http://www.systemc.org > 115 D.3. INSTALAR O ARCHC Os comandos a seguir são realizados no terminal: 1. Acessar o diretório do pacote ArchC: cd /home/myuser/files/archc2 2. Configurando a instalação (comando único): ./configure --with-binutils=/home/myuser/files/binutils --with-gdb=/home/myuser/files/gdb --with-systemc=/usr/local/systemc --with-tlm=/home/myuser/files/tlm/tlm --prefix=/home/myuser/files/archc2 3. Instalando: make make install D.4. GERANDO O MONTADOR Os comandos a seguir são realizados no terminal: 1. Acessar o diretório do MIPS-I: cd /home/myusers/files/mips 2. Cria diretório de instalação: mkdir /home/myusers/files/mips/install-dir 3. Configurar a instalação do montador: ../archc2/bin/acbingen.sh –i/home/myusers/files/mips/install-dir amips1_4 mips1.ac 116 - D.5. UTILIZANDO O MONTADOR Os comandos a seguir são realizados no terminal: 1. Para utilizar o montador, primeiramente deve-se ter um arquivo que contenha o assembly a ser montado. 2. Gerando um objeto a partir de um código assembly: /home/myusers/files/mips/install-dir/bin/mips1_1-as –o ArquivoDeSaída.o ArquivoASM.s Este comando gera um objeto baseado no formato ELF. Para visualizar o conteúdo do objeto utilize os comandos: readelf –x1 ArquivoObjeto.o readelf –x2 ArquivoObjeto.o D.6. GERANDO O SIMULADOR Os comandos a seguir são realizados no terminal: 1. Acessar o diretório do MIPS-I: cd /home/myusers/files/mips 2. Verificar parâmetros para a construção do simulador: /home/myusers/files/archc2/acsim --help 3. Gerar arquivos para configuração do simulador: /home/myusers/files/archc2/acsim mips1.ac -s 4. Instalando o simulador: make –f Makefile.archc 5. Caso seja necessário desinstalar o simulador utilize: make –f Makefile.archc distclean 117 D.7. UTILIZANDO O SIMULADOR Os comandos a seguir são realizados no terminal: 1. Simulando o arquivo objeto gerado pelo montador: /home/myusers/files/mips/mips1.x –load=/home/myusers/files/mips/install-dir/bin/ArquivoDeSaida.o D.8. UTILIZANDO O LIGADOR O ligador é gerado juntamente com o montador conforme apresentado anteriormente. O comando abaixo é utilizado para gerar o executável com o ligador: /home/myusers/files/mips/install-dir/bin/mips1_1-ld ArquivoASM.o –Ttext=0x00 –Tdata=0x00 118 –o ArquivoDeSaída.x E PLANO DE TESTE UNITÁRIO Neste Apêndice está disponível o plano de teste utilizado para validar cada instrução do conjunto de instruções do µBIP. Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC add_1.s addi_1.s ADDI and_1.s AND andi_1.s ANDI beq_1.s BEQ 0x0004 0x0004 0x0 0x0 ldi 0x003 addi 0x004 0x0002 0x0007 0x0 0x0 ldi 0x00C sto $15 ldi 0x007 and $15 0x0004 0x0004 0x0 0x0 ldi 0x00C andi 0x007 0x0002 0x0004 0x0 0x0 0x0004 0x0055 0x0 0x0 BGE ldi 0x004 subi 0x004 bge __end ldi 0x055 __end: 0x0004 0x0000 0x1 0x0 BGE ldi 0x005 subi 0x004 bge __end ldi 0x055 __end: bge_3.s 0x0004 0x0000 0x1 0x0 BEQ ldi 0x005 subi 0x004 beq __end ldi 0x055 __end: bge_2.s N 0x001 $14 0x003 $14 ldi 0x004 subi 0x004 beq __end ldi 0x055 __end: bge_1.s Z Memória ADD ldi sto ldi add beq_2.s ACC 0x0004 0x0001 0x0 0x0 BGE ldi 0x004 subi 0x005 bge __end ldi 0x055 __end: 0x0004 0x0055 0x0 0x1 119 M[0x000E]=0x0001 M[0x000F]=0x000C Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC bgt_1.s BGT 0x0004 0xFFFF 0x0 0x1 BLT ldi 0x003 subi 0x004 blt __end ldi 0x055 __end: btl_2.s 0x0004 0xFFFF 0x1 0x0 BLE ldi 0x005 subi 0x004 ble __end ldi 0x055 __end: btl_1.s 0x0004 0x0000 0x1 0x0 BLE ldi 0x003 subi 0x004 ble __end ldi 0x055 __end: ble_3.s 0x0004 0x0055 0x0 0x1 BLE ldi 0x004 subi 0x004 ble __end ldi 0x055 __end: ble_2.s 0x0004 0x0055 0x0 0x0 BGT ldi 0x004 subi 0x005 bgt __end ldi 0x055 __end: ble_1.s N 0x0004 0x0001 0x0 0x0 ldi 0x003 subi 0x003 bgt __end ldi 0x055__end: bgt_3.s Z BGT ldi 0x004 subi 0x003 bgt __end ldi 0x055 __end: bgt_2.s ACC 0x0004 0xFFFF 0x0 0x1 BLT ldi 0x003 subi 0x003 blt __end ldi 0x055 __end: 0x0004 0x0055 0x0 0x0 120 Memória Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC btl_3.s jmp_1.s ld_1.s ldi_1.s not_1.s 0x0004 0x0055 0x0 0x0 0x0004 0x0001 0x0 0x0 0x0004 0x0055 0x0 0x0 CALL ldi 0x003 sto $14 ldi 0x002 sto $15 call __sum addi 0x001 jmp __end __sum: ld $14 add $15 return __end: htl_1.s Memória BNE ldi 0x003 subi 0x003 bne __end ldi 0x055 __end: call_1.s N BNE ldi 0x004 subi 0x003 bne __end ldi 0x055 __end: bne_2.s Z BLT ldi 0x005 subi 0x004 blt __end ldi 0x055 __end: bne_1.s ACC HTL 0x000A 0x0006 0x0 0x0 ldi 0x004 hlt ldi 0x055 0x0002 0x0004 0x0 0x0 ldi 0x004 jmp __end ldi 0x055 __end: 0x0003 0x0004 0x0 0x0 M[0x000E]=0x0003 M[0x000F]=0x0002 JMP LD LDI NOT ldi 0x044 sto $15 ldi 0x055 sto $16 ld $15 ldi 0x055 ldi 0x00F not 0x0005 0x0044 0x0 0x0 0x0001 0x0055 0x0 0x0 0x0002 0xFFF0 0x0 0x1 121 M[0x000F]=0x0044 M[0x0010]=0x0055 Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC ldv_1.s or_1.s ori_1.s LDV OR ORI .text main: ldi 1 sto $2 sto $0 for: subi 2 bgt endfor ld $0 subi 1 sto $indr ldv $2 addi 1 sto $1 ld $0 sto $indr ld $1 stov $2 ld $0 addi 1 sto $0 jmp for endfor: ldi 0 sto $0 print: subi 2 bgt endprint ld $0 sto $indr ldv $2 sto $port0_data ld $0 addi 1 sto $0 jmp print endprint: hlt endmain: ldi 0x008 sto $15 ldi 0x007 or $15 ldi 0x008 ori 0x007 ACC Z N Memória 0x001F 0x0001 0x0 0x0 M[0x0000]=0x0003 M[0x0001]=0x0003 M[0x0002]=0x0001 M[0x0003]=0x0002 M[0x0004]=0x0003 0x0004 0x000F 0x0 0x0 M[0x000F]=0x0000 0x0002 0x000F 0x0 0x0 122 Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC retint_1.s RETI return_1.s RETURN jmp __start jmp __intr __start: ldi 0x000 sto $tmr0_config ldi 0x003 sto $int_config ldi 0x000 sto $tmr0_value volta: ld $110 subi 0x100 bne volta ld $110 jmp __end __intr: ld $110 addi 0x100 sto $110 retint __end: ldi 0x003 sto $14 ldi 0x002 sto $15 call __sum addi 0x001 jmp __end __sum: ld $14 add $15 return addi 0x055 __end: ACC Z N Memória 0x0011 0x0100 0x0 0x0 M[t0con]=0x0003 M[intrc]=0x0003 M[tmr00]=0xXXXX M[0x000A]=0x0100 0x000B 0x0006 0x0 0x0 M[0x000E]=0x0003 M[0x000F]=0x0002 sll_1.s SLL ldi 0x004 sll 0x001 0x0003 0x0004 0x0 0x0 srl_1.s SRL ldi 0x004 srl 0x001 0x0002 0x0002 0x0 0x0 xori_1.s XOR ldi 0x005 xori 0x00A 0x0002 0x000F 0x0 0x0 sto_1.s STO ldi 0x055 sto $15 0x0002 0x0055 0x0 0x0 123 M[0x000F]=0x0055 Arquivo Instrução Seqüência de instruções para o teste Resultado esperado após a seqüência de instruções PC stov_1.s sub_1.s sub_2.s sub_3.s STO SUB SUB SUB .text main: ldi 1 sto $2 sto $0 for: #ld $0 subi 2 bgt endfor ld $0 subi 1 sto $indr ldv $2 addi 1 sto $1 ld $0 sto $indr ld $1 stov $2 ld $0 addi 1 sto $0 jmp for endfor: hlt endmain: ldi 0x00A sto $15 ldi 0x00A sub $15 ldi 0x004 sto $15 ldi 0x005 sub $15 ldi 0x004 sto $15 ldi 0x003 sub $15 ACC Z N Memória 0x0013 0x0001 0x0 0x0 M[0000]=0x0003 M[0001]=0x0003 M[0002]=0x0001 M[0003]=0x0002 M[0004]=0x0003 0x0004 0x0000 0x1 0x0 M[0x000F]=0x000A 0x0004 0x0001 0x0 0x0 M[0x000F]=0x0004 0x0004 0xFFFF 0x0 0x1 M[0x000F]=0x000A subi_1.s SUBI ldi 0x002 subi 0x005 0x0002 0xFFFD 0x0 0x1 subi_2.s SUBI ldi 0x005 subi 0x002 0x0002 0x0003 0x0 0x0 subi_3.s SUBI 0x0002 0x0000 0x1 0x0 xor_1.s XOR ldi 0x005 subi 0x005 ldi 0x005 sto $15 ldi 0x00A xor $15 0x0004 0x000F 0x0 0x0 124 M[0x000F]=0x0005 F TESTBENCH (DALTON-PROJECT) Neste apêndice, estão disponíveis todos os códigos fontes em assembly dos testes realizados a partir dos testbenchs apresentados por Dalton-Project. Ao final é apresentado uma tabela com os resultados da simulação no ArchC do µBIP. F.1. TESTE: CAST.S .data x : .word 0x00 .text __start: ldi 0 sto $port0_dir sto $port1_dir ldi 0x12 sll 8 ori 0x34 sto x andi 0xFF sto $port0_data ld x srl 8 andi 0xFF sto $port1_data __end: hlt F.2. TESTE: DIVMUL.S .data x y q r p i .text : : : : : : .word .word .word .word .word .word 0x00 0x00 0x00 0x00 0x00 0x00 jmp main #-------Funcao de Divisao divisao: ldi 0 #Inicia o contador com 0 sto $102 jmp div2 div1: ld $102 #incrementa o contador addi 1 sto $102 div2: ld $100 sub $101 sto $100 bge div1 ld $102 return 125 #-------Funcao Modulo modulo: ldi 0 #Inicia o contador com 0 sto $102 jmp mod2 mod1: ld $102 #incrementa o contador addi 1 sto $102 mod2: ld $100 sto $103 sub $101 sto $100 bge mod1 ld $103 return #--------Funcao Multiplicacao multiplicacao: ldi 0 sto $102 mult1: ld $101 subi 0 beq mult2 ld $102 add $100 sto $102 ld $101 subi 1 sto $101 jmp mult1 mult2: ld $102 return #--------Main main: ldi 0 sto $port0_dir sto $port1_dir ldi 134 sto x ldi 1 sto y ldi 0 sto i fori: ld i subi 12 bge endfor ld y addi 1 sto y ld i addi 1 sto i jmp fori endfor: ld x sto $100 126 ld y sto $101 call divisao sto q ld x sto $100 ld y sto $101 call modulo sto r ld q sto $100 ld y sto $101 call multiplicacao add r sto p ld q sto $port0_data ld r sto $port0_data ld p sto $port0_data while_true: #jmp while_true hlt F.3. TESTE: FIB.S .data x n buf :.word 0x00 :.word 0x00 :.word 0x00 .text jmp main ldi sto ldi sto ldi stov sto stov 2 x #i=2 0 $indr #indr=0 1 buf #buf[0] = 1 $indr buf #buf[1] = 1 ld sub bge ld subi sto ldv sto ld subi sto ldv add sto ld x n fib2 x 1 $indr buf $102 x 2 $indr buf $102 $103 x fib: fib1: # if ( i >= n) go to fib2 # temp1 = buf[i-1] # ACC = buf[i-2] + temp1 # temp2 = ACC 127 sto ld stov ld addi sto jmp $indr $103 buf # buf[i] = temp2 x 1 x # i = i + 1 fib1 fib2: return #------------- PRINT FUNCTION print: ldi 0 #init i sto x print_fori: sub n bge print_endfori # if (i >= n) goto print_endfori ld x sto $indr ldv buf sto $port0_data ld x addi 1 sto x jmp print_fori print_endfori: return main: ldi 0 sto $port0_dir ldi 10 sto n call fib call print while_true: #jmp while_true end: hlt F.4. TESTE: GCD.S .data x : .word 0x000 y : .word 0x000 .text jmp main ld sub beq blt x y gcd_end gcd2 sto sto jmp x $port0_data gcd ld sub sto sto jmp y x y $port1_data gcd gcd: gcd1: gcd2: 128 gcd_end: ld x return main: ldi 0 sto $port0_dir sto $port1_dir ldi 47 sto x ldi 11 sto y call gcd sto $port1_data while_true: #jmp while_true hlt F.5. TESTE: INT2BIN.S .data x : .word 0x00 i : .word 0x00 .text jmp main check: beq print0 ldi 1 print0: sto $port0_data return main: ldi 0 sto $port0_dir ldi 0xaa sto x ldi 1 sto i for: ld x and i call check ld i sll 1 sto i subi 0x100 bne for while_true: #jmp while_true end: hlt F.6. TESTE: NEGCNT.S .data x : .word 0x000 .text ldi sto ldi sto 0 $port0_dir -960 x 129 for: ld i subi -950 bge endfor ld x andi 255 sto $port0_data ld x addi 1 sto x jmp for endfor: while_true: #jmp while_true hlt F.7. TESTE: SORT.S .data i :.word 0 j :.word 0 n :.word 0 buf :.word 0,0,0,0,0,0,0,0,0,0 .text jmp main #------------- SORT FUNCTION sort: ldi 0 #init i sto i fori: ld i sub n bge endfori # if (i >= n) goto endfori ld i sto j # init j=i forj: ld j sub n bge endforj # if (j >= n ) goto endforj ld i sto $indr ldv buf sto $100 # $100 = buf[i] ld j sto $indr ldv buf sto $101 # $101 = buf[j] ld j addi 1 sto j # j++ ld $100 sub $101 ble forj # if ( buf[i] <= buf[j] ) goto forj ld $100 stov buf # buf[j] = buf[i]($100) ld i sto $indr ld $101 stov buf # buf[i] = buf[j]($101) jmp forj # goto forj 130 endforj: ld i addi 1 sto i # i++ jmp fori # goto fori endfori: ldi 0 sto $port0_data return #------------- PRINT FUNCTION print: ldi 0 #init i sto i print_fori: sub n bge print_endfori # if (i >= n) goto print_endfori ld i sto $indr ldv buf sto $port0_data ld i addi 1 sto i jmp print_fori print_endfori: return #------------- MAIN main: ldi 0 sto $port0_dir ldi 10 sto n ldi 0 sto $indr ldi 19 stov buf # buf[0] = 19 ldi 1 sto $indr ldi 18 stov buf # buf[1] = 18 ldi 2 sto $indr ldi 17 stov buf # buf[2] = 17 ldi 3 sto $indr ldi 16 stov buf # buf[3] = 16 ldi 4 sto $indr ldi 15 stov buf # buf[4] = 15 ldi 5 sto $indr ldi 14 stov buf # buf[5] = 14 ldi 6 sto $indr ldi 13 stov buf # buf[6] = 13 131 ldi 7 sto $indr ldi 12 stov buf # buf[7] = 12 ldi 8 sto $indr ldi 11 stov buf # buf[8] = 11 ldi 9 sto $indr ldi 10 stov buf # buf[9] = 10 call sort call print while_true: #jmp while_true hlt end: F.8. TESTE: SQROOT.S .data x :.word 0 y :.word 0 xx :.word 0 yy :.word 0 xx_yy :.word 0 sqrt_xx_yy :.word 0 .text jmp main # Square. square: sto $100 sto $101 call multiplication return multiplication: ldi 0 sto $102 mult1: ld $101 subi 0 beq mult2 ld $102 add $100 sto $102 ld $101 subi 1 sto $101 jmp mult1 mult2: ld $102 return sqroot: sto $110 ldi 1 sto $111 sto $112 sqr1: ld $111 132 sto $100 sto $101 call multiplication sub $110 beq sqr3 bgt sqr2 ld $111 sto $112 addi 1 sto $111 jmp sqr1 sqr2: ld $112 return sqr3: ld $111 return main: ldi 0 sto $port0_dir sto $port1_dir ldi 3 sto x # x = 3 ldi 4 sto y # y = 4 ld x call square sto xx # xx = x * x sto $port0_data ld y call square sto yy #yy = y * y sto $port1_data ld xx add yy sto xx_yy #xx_yy = xx + yy sto $port0_data call sqroot sto sqrt_xx_yy sto $port1_data hlt F.9. TESTE: XRAM.S .text main: ldi sto sto for: subi bgt ld subi sto ldv addi sto ld sto ld stov ld addi 1 $2 $0 1021 endfor $0 1 $indr $2 1 $1 $0 $indr $1 $2 $0 1 # buffer[0] = 1 # x = 1 # 1024 - 2($0 and $1) = 1022 # if (x >= 1022) goto endfor # temp1 = buffer[i - 1] + 1 # buffer[i] = buffer[i - 1] + 1 133 sto $0 jmp for endfor: while_true: #jmp while_true hlt endmain: F.10. RESULTADO DOS TESTES Instrução/ Testes cast divmul fib gcd int2bin negcnt sort sqroot xram HLT 1 1 1 1 1 1 1 1 1 STO LD LDI ADD ADDI SUB SUBI BEQ BNE BGT BGE BLT BLE JMP NOT AND ANDI OR ORI XOR XORI SLL SRL STOV LDV RETURN RETINT CALL Total Executadas: 4 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 1 1 0 0 0 0 0 13 123 131 7 14 44 22 40 14 0 0 35 0 0 28 0 0 0 0 0 0 0 0 0 0 0 3 0 3 465 84 69 6 8 18 20 16 0 0 0 20 0 0 19 0 0 0 0 0 0 0 0 0 10 26 2 0 2 301 23 15 3 0 0 14 0 10 0 0 0 9 0 10 0 0 0 0 0 0 0 0 0 0 0 1 0 1 87 19 16 7 0 0 0 8 8 8 0 0 0 0 1 0 8 0 0 0 0 0 8 0 0 0 8 0 8 100 22 31 2 0 10 0 11 0 0 0 11 0 0 10 0 0 10 0 0 0 0 0 0 0 0 0 0 0 108 385 471 25 0 75 142 0 0 0 0 87 0 55 66 0 0 0 0 0 0 0 0 0 100 120 2 0 2 1531 88 93 11 23 4 5 51 34 0 4 0 0 0 27 0 0 0 0 0 0 0 0 0 0 0 10 0 10 361 4086 4084 1 0 2042 0 2043 0 0 1022 0 0 0 1021 0 0 0 0 0 0 0 0 0 1021 1021 0 0 0 16342 Total Utilizadas: 8 13 14 10 12 9 13 13 10 %Utilização do Conjunto de Instrução 27 % 44% 41% 31% 44% 44% 34% 48% 34% 134 Total Total Executadas Ocorrência 9 9 4834 4911 64 45 2193 203 2169 66 8 1026 153 9 55 1182 0 8 12 0 1 0 0 9 1 1131 1167 26 0 26 19308 9 9 9 3 6 5 6 4 1 2 4 1 1 8 0 1 2 0 1 0 0 2 1 3 3 6 0 6 24 82% G BLOCOS VHDL Bloco: Frequency Divider (frequencydivider.vhd) Comportamento: Implementação de um bloco que permite dividir o ciclo do clock em N vezes. Utilizado quando o clock fornecido para o µBIP é maior que o permitido. INTERFACE clk_in clk_out IN OUT Clock de entrada ao µBIP Clock dividido conforme configuração Bloco: Data bus mux (databusmux.vhd) Comportamento: Implementação de um multiplexador que determina através de um endereço qual dado que deve passar pelo barramento. INTERFACE target_addr ram_data port0_data port1_data tmr0_data intr_data mcu_config_data cpu_data IN IN IN IN IN IN IN OUT Endereço do registrador Entrada do conteúdo da RAM Entrada do conteúdo da port0 Entrada do conteúdo da port1 Entrada do conteúdo do timer 0 Entrada do conteúdo do controlador de interrupção Entrada do conteúdo do registrador mcu_config Saída com o conteúdo determinado pelo target_addr. 135 Bloco: Edge Detector(edge_detector.vhd) Comportamento: Implementação de um bloco capaz de verificar a presença de uma conforme configuração, se verificado gera uma interrupção. A configuração de Borda de Subida / Borda de Descida é realizada através do endereço do registrador MCU_CONFIG no bit 0. Registradores Internos: MCU_CONFIG(0) INTERFACE clk rst addr din dout rd_data IN IN IN IN OUT IN wr_data IN pin intr IN OUT Entrada do clock Reseta o bloco quando em ‘1’ Barramento: Endereço Barramento: Dado de entrada Barramento: Dado de saída Barramento: Permita a leitura do registrador indicado por addr Barramento: Permite a escrita do valor de din no endereço indicado por addr Sinal a ser verificado a presença de borda Interrupção gerada no caso de identificação de borda 136 Bloco: Interrupt Controller (interruptcontroller.vhd) Comportamento: Implementação de um controlador responsável por gerenciar um conjunto de interrupções e interromper a CPU quando necessário. Registradores: int_config e int_status INTERFACE clk rst addr din dout rd_data IN IN IN IN OUT IN wr_data IN irq IN intr OUT Entrada do clock Reseta o bloco quando em ‘1’ Barramento: Endereço Barramento: Dado de entrada Barramento: Dado de saída Barramento: Permita a leitura do registrador indicado por addr Barramento: Permite a escrita do valor de din no endereço indicado por addr Interrupt Request: Solicita ao controlador uma interrupção da CPU. Interrupção gerada no caso uma interrupção(irq) solicitada esteja ativa. 137 Bloco: Timer (timer.vhd) Comportamento: Implementação de temporizador que gera uma interrupção em intervalos programados. Registradores: trm0_config e tmr0_value INTERFACE clk rst addr din dout rd_data IN IN IN IN OUT IN wr_data IN Intr OUT Entrada do clock Reseta o bloco quando em ‘1’ Barramento: Endereço Barramento: Dado de entrada Barramento: Dado de saída Barramento: Permita a leitura do registrador indicado por addr Barramento: Permite a escrita do valor de din no endereço indicado por addr Interrupção gerada no caso do contador interno estourar. Bloco: RAM (ram.vhd) Comportamento: Implementação de uma memória do tipo RAM. INTERFACE clk addr din dout wren IN IN IN OUT IN Entrada do clock Endereço Dado a ser escrito na memória de dados Dado lido da memória de dados Permite a escrita de do dado (din) no endereço dado (addr). 138 Bloco: I/O Pin (io_pin.vhd) Comportamento: Implementação um pino de interface externa bidirecional com seletor de direção. Registradores: bit especifico de portX_dir e portX_data INTERFACE clk rst data_bus_in data_bus_out rd_port IN IN IN OUT IN rd_tris IN wr_port IN wr_tris IN pin IN/OUT Entrada do clock Reseta o bloco quando em ‘1’ Dado de entrada Dado de saída Permite a leitura do registrador com o conteúdo da porta quando configurada como entrada. Permite a leitura do registrador tris (configuração da direção da porta). Permite a escrita do valor de data_bus_in no pino quando configurado com saída. Permite escrever o valor de data_bus_in no registrador de configuração da direção da porta. Representa o pino de interface externa. 139 Bloco: I/O Port (io_port.vhd) Comportamento: Implementação de um vetor de I/O Pins, ou seja, uma porta de interface externa bidirecional. Registradores: portX_dir e portX_data INTERFACE clk rst addr din dout rd_data IN IN IN IN OUT IN wr_data IN pin IN/OUT Entrada do clock Reseta o bloco quando em ‘1’ Barramento: Endereço Barramento: Dado de entrada Barramento: Dado de saída Barramento: Permita a leitura do registrador indicado por addr Barramento: Permite a escrita do valor de din no endereço indicado por addr Representa os pinos de interface externa. Bloco: ROM (rom.vhd) Comportamento: Implementação de uma memória do tipo ROM. INTERFACE clk addr dout IN IN OUT Entrada do clock Endereço da instrução. Instrução lida pelo endereço. 140 Bloco: Pilha (stack.vhd) Comportamento: Implementação de uma memória do tipo PILHA. INTERFACE clk rst cmd_insert cmd_remove data_in data_out IN IN IN IN IN OUT Entrada do clock Reinicializa o bloco Comando para inserir o dado (data_in) na pilha Comando para remover o dado da pilha Dado a ser inserido na pilha Retorno do topo da pilha Bloco: FunctionUnit (functionunit.vhd) Comportamento: Implementação da unidade funcional que comporta instruções aritméticas, lógicas e de deslocamentos.. INTERFACE operandA operandB operation result status IN IN IN OUT OUT Operando Operando Codigo da operação Resultado da operação Informação sobre os resultado. 141 Bloco: Datapath (datapath.vhd) Comportamento: Implementação o cominho de controle da CPU do µBIP. INTERFACE clk rst is_vector IN IN IN SelA IN SelB IN wr_acc wr_indr operand din fu_op addr dout status IN IN IN IN IN OUT OUT OUT Entrada do clock Reinicializa o bloco Indica que a instrução atual uso o modulo de manipulação de vetores Determina qual a origem do primeiro operando da unidade funcional Determina qual a origem do segundo operando da unidade funcional Habilita a escrita no registrador ACC Habilita a escrita no registrador INDR Operando da instrução Dado vindo da memória de dados ou SFR Indica a operação da unidade funcional Endereço da memória de dados ou SFR Dado de saída do datapath (ACC) Rediriciona as informações sobre o resultado da unidade funcional 142 Bloco: Unidade de Controle (control.vhd) Comportamento: Implementação o cominho de controle da CPU do µBIP. INTERFACE clk rst intr din status IN IN IN IN IN ack OUT is_vector OUT SelA OUT SelB OUT wr_acc wr_indr operand rd_data wr_data fu_op Addr OUT OUT OUT OUT OUT OUT OUT Entrada do clock Reinicializa o bloco Entrada da interrupção vinda do controlador de interrupções Entrada da instrução vinda da ROM Entrada das informações do resultado da unidade funcional, para tomada de decisão referente a saltos. Saída para o controlador de interrupção que informa-o o recebimento da interrupção. Indica que instrução irá utilizar o modulo de manipulação de vetores Determina qual a origem do primeiro operando da unidade funcional Determina qual a origem do segundo operando da unidade funcional Habilita a escrita no registrador ACC Habilita a escrita no registrador INDR Operando da instrução Habilita a leitura na memória RAM ou SFR Habilita a escrita na memória RAM ou SFR Indica a operação da unidade funcional Endereço da memória ROM. 143 Bloco: CPU (cpu.vhd) Comportamento: Implementação o cominho de controle e unidade de controle do µBIP. INTERFACE clk rst intr rom_din cpu_din ack IN IN IN IN IN OUT rd_data wr_data cpu_dout target_addr rom_addr OUT OUT OUT OUT OUT Entrada do clock Reinicializa o bloco Entrada da interrupção vinda do controlador de interrupções Entrada da instrução vinda da ROM Entrada de dados da memória de dados ou SFR Saída para o controlador de interrupção que informa-o o recebimento da interrupção. Habilita a leitura na memória RAM ou SFR Habilita a escrita na memória RAM ou SFR Dado de saída da CPU Endereço do registrador ou posição de memória Endereço de instrução da memória ROM. Bloco: µBIP (ubip.vhd) Comportamento: Bloco que representa o µBIP, ou seja, contêm todos os outros blocos. INTERFACE clk rst port0_data port1_data IN IN IN/OUT IN/OUT Entrada do clock Reinicializa o bloco Pinos de Entrada e Saída da port0 Pinos de Entrada e Saída da port1 144 H REGISTRADORES Este apêndice apresenta maiores informações sobre os registradores especiais do µBIP. As tabelas a seguir possuem o nome do registrador, seu endereço e uma descrição. Além dessas informações possui ainda informação quanto ao acesso: (i) R, bit somente para leitura (read); (ii) R/W, bit de leitura e escrita (read/write); e (iii) U para os bits não implementados (Unimplemented). Para alguns registradores é apresentado a nomenclatura por bit. A linha após a descrição do registrador é posição do bit. Registrador: port0_dir Descrição: Endereço: 0x400 Define quais pinos são saídas e quais pinos são entradas 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W D0_15 D0_14 D0_13 D0_12 D0_11 D0_10 D0_9 D0_8 D0_7 D0_6 D0_5 D0_4 D0_3 D0_2 D0_1 D0_0 D0_X 0 1 = = O pino é definido como saída. O pino é definido como entrada Registrador: port0_data Descrição: 15 14 R/W R/W P0_15 P0_14 Endereço: 0x401 Possui os dados dos pinos de E/S da porta port0 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W P0_13 P0_12 P0_11 P0_10 P0_9 P0_8 P0_7 P0_6 P0_5 P0_4 P0_3 P0_2 P0_1 P0_0 Registrador: port1_dir Descrição: Endereço: 0x402 Define quais pinos são saídas e quais pinos são entradas 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W D1_15 D1_14 D1_13 D1_12 D1_11 D1_10 D1_9 D1_8 D1_7 D1_6 D1_5 D1_4 D1_3 D1_2 D1_1 D1_0 D1_X 0 1 = = O pino é definido como saída. O pino é definido como entrada Registrador: port1_data Descrição: 15 14 R/W R/W P1_15 P1_14 Endereço: 0x403 Possui os dados dos pinos de E/S da porta port0 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W P1_13 P1_12 P1_11 P1_10 P1_9 P1_8 P1_7 P1_6 P1_5 P1_4 P1_3 P1_2 P1_1 P1_0 145 Registrador: tmr0_config Endereço: 0x410 Descrição: Registrador de configuração do timer 0, mais especificamente o prescaler do timer. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 U U U U U U U U U U U U U R/W R/W R/W - - - - - - - - - - - - - PS2 PS1 PS0 Configuração do prescaler: PS2 PS1 PS0 0 0 0 = 1:1 0 0 1 = 1:2 0 1 0 = 1:4 0 1 1 = 1:8 1 0 0 = 1:16 1 0 1 = 1:32 1 1 0 = 1:64 1 1 1 = 1:128 Registrador: tmr0_value Endereço: 0x411 Descrição: Possui o valor atual do contador interno do timer 0. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W Registrador: int_config Endereço: 0x420 Descrição: Registrador de configuração do controlador de interrupção. Indica quais interrupções estão habilitadas 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 U U U U U U U U U U U U U R/W R/W R/W - - - - - - - - - - - - - EDIE T0IE GIE GIE T0IE EDIE Chave geral de Interrupção - General Interrupt Enable 0 = Chave geral de interrupção desabilitada 1 = Chave geral de interrupção habilitada Interrupção de estouro do Timer 0 (tmr0) - Timer 0 Interrupt Enable 0 = Interrupção do Timer 0 desabilitada 1 = Interrupção do Timer 0 habilitada Interrupção externa no P0_0 - Edge detect Interrupt Enable 0 = Interrupção externa no P0_0 desabilitada 1 = Interrupção externa no P0_0 habilitada 146 Registrador: int_status Endereço: 0x421 Descrição: Registrador que identifica as interrupções solicitadas 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 U U U U U U U U U U U U U U R/W R/W - - - - - - - - - - - - - - EDIE T0IE Identificação da Interrupção de estouro do Timer 0 (tmr0) - Timer 0 Interrupt Flag 0 = Não ocorreu interrupção 1 = Ocorreu interrupção do Timer 0 EDIF Interrupção por detecção de borda (P0_0)- Edge detect Interrupt Enable 0 = Não ocorreu interrupção 1 = Ocorreu interrupção externa no P0_0 T0IF Registrador: mcu_config Endereço: 0x430 Descrição: Registrador de configuração geral do microcontrolador 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 U U U U U U U U U U U U U U U - - - - - - - - - - - - - - 0 R/W EDG EDG Identifica a borda que gerará a interrupção externa no P0_0 0 = borda de descida borda de 1 = subida Registrador: indr Endereço: 0x431 Descrição: Possui o índice do vetor. Utilizado pelas instruções LDV e STOV 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W R/W 147 Registrador: status Descrição: Endereço: 0x432 Registrador que possui informações sobre o resultado da unidade funcional 15 14 13 12 11 10 9 8 7 6 5 4 3 U U U U U U U U U U U U U - - - - - - - - - - - - - Z N C 2 1 0 R R R C N Z Indica que o resultado da unidade funcional é zero O resultado da unidade funcional é diferente de 0 = zero 1 = O resultado da unidade funcional é zero Indica que o resultado da unidade funcional é um número menor que zero O resultado da unidade funcional é maior ou igual a zero 0 = 1 = O resultado da unidade funcional é menor que zero Indica a ocorrência de carry-out/borrow na operação aritmética 0 = Não ocorreu um carry-out/borrow 1 = Ocorreu um carry-out/borrow 148