Document

Propaganda
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
Download