Post on 07-Apr-2020
UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR
CURSO DE CIÊNCIA DA COMPUTAÇÃO
COMPILADOR PICOBLAZE C (PBlazeC)
Área de Compiladores
por
Caroline Farias Salvador
André Luís Alice Raabe, Dr. Orientador
Cesar Albenes Zeferino, Dr. Co-orientador
Itajaí (SC), junho de 2009
UNIVERSIDADE DO VALE DO ITAJAÍ CENTRO DE CIÊNCIAS TECNOLÓGICAS DA TERRA E DO MAR
CURSO DE CIÊNCIA DA COMPUTAÇÃO
COMPILADOR PICOBLAZE C (PBlazeC)
Área de Compiladores
por
Caroline Farias Salvador 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: André Luís Alice Raabe, Dr.
Itajaí (SC), junho de 2009
ii
SUMÁRIO
LISTA DE ABREVIATURAS.................................................................. iv
LISTA DE FIGURAS ................................................................................. v
LISTA DE TABELAS ............................................................................... vi
RESUMO ................................................................................................... vii
ABSTRACT .............................................................................................. viii
1 INTRODUÇÃO........................................................................................ 1
1.1 PROBLEMATIZAÇÃO ................................................................................... 2
1.1.1 Formulação do Problema .............................................................................. 2
1.1.2 Solução Proposta ............................................................................................ 3
1.2 OBJETIVOS ..................................................................................................... 3
1.2.1 Objetivo Geral ................................................................................................ 3
1.2.2 Objetivos Específicos...................................................................................... 3
1.3 METODOLOGIA ............................................................................................. 4
1.4 ESTRUTURA DO TRABALHO ..................................................................... 4
2 FUNDAMENTAÇÃO TEÓRICA .......................................................... 6
2.1 MICROCONTROLADOR PICOBLAZE ........................................................ 6
2.1.1 Características do PicoBlaze ........................................................................... 7
2.1.2 Ambiente de Desenvolvimento ...................................................................... 13
2.2 PCCOMP .......................................................................................................... 14
2.2.1 Características do PCCOMP ........................................................................ 15
2.2.2 Análise ............................................................................................................ 17
2.3 COMPILADORES ........................................................................................... 20
2.3.1 Geração de Código Intermediário ................................................................ 22
2.3.2 Geração de Código ........................................................................................ 26
3 PROJETO .............................................................................................. 36
3.1 ANÁLISE DE REQUISITOS .......................................................................... 36
3.1.1 Requisitos Funcionais .................................................................................... 36
3.1.2 Requisitos Não Funcionais ............................................................................ 37
3.1.3 Regras de Negócio ......................................................................................... 37
3.2 DIAGRAMAS DE CASOS DE USO ............................................................... 38
3.2.1 UC01 Implementa Aplicação ........................................................................ 38
3.2.2 UC02 Implementa Biblioteca ........................................................................ 39
3.2.3 UC03 Adiciona Biblioteca ............................................................................. 39
3.2.4 UC04 Compila Aplicação .............................................................................. 39
3.2.5 UC05 Testa Aplicação ................................................................................... 39
3.2.6 UC06 Acessa Ajuda ....................................................................................... 40
3.3 DEFINIÇÃO DA GRAMÁTICA .................................................................... 40
iii
4 DESENVOLVIMENTO ........................................................................ 42
4.1 DEFINIÇÃO DE ASPECTOS SEMÂNTICOS .............................................. 42
4.2 GERAÇÃO DE CÓDIGO INTERMEDIÁRIO.............................................. 46
4.2 POLÍTICAS DE ALOCAÇÃO DE MEMÓRIA E REGISTRADORES ...... 47
4.3 INTERFACE .................................................................................................... 48
4.4 VALIDAÇÃO DO CÓDIGO ASSEMBLY GERADO ................................... 52
4.4 LIMITAÇÕES .................................................................................................. 55
5 CONCLUSÕES ...................................................................................... 56
REFERÊNCIAS BIBLIOGRÁFICAS ................................................... 58
A TESTBENCH ........................................................................................ 60
A.1 FIB.C ................................................................................................................ 60
A.2 SQROOT.C ...................................................................................................... 63
A.2.1 Assembly gerado pelo PBlazeC .................................................................... 66
A.3 DIVMUL.C ...................................................................................................... 67
A.3.1 Assembly gerado pelo PBlazeC .................................................................... 71
A.4 NEGCNT.C ...................................................................................................... 72
A.4.1 Assembly gerado pelo PBlazeC .................................................................... 73
A.5 SORT.C ............................................................................................................ 73
A.6 XRAM.C .......................................................................................................... 77
A.7 CAST.C ............................................................................................................ 79
A.7.1 Assembly gerado pelo PBlazeC .................................................................... 82
A.8 GCD.C .............................................................................................................. 82
A.8.1Assembly gerado pelo PBlazeC ..................................................................... 84
A.9 INT2BIN.C ....................................................................................................... 84
A.9.1 Assembly gerado pelo PBlazeC .................................................................... 86
B CÓDIGO FONTE ................................................................................. 88
B.1 ESPECIFICAÇÃO SINTÁTICA DA LINGUAGEM ................................... 88
B.2 CÓDIGO FONTE SEMANTICO.CS ............................................................. 90
C ARQUIVOS DE MEMÓRIA DO PicoBlaze ................................... 115
C.1 SQROOT.VHD .............................................................................................. 115
C.2 DIVMUL.VHD .............................................................................................. 119
C.3 NEGREG.VHD .............................................................................................. 123
C.4 CAST.VHD .................................................................................................... 127
C.5 GCD.VHD ...................................................................................................... 131
C.6 INT2BIN.VHD ............................................................................................... 135
iv
LISTA DE ABREVIATURAS
ALU Arithmetic Logic Unit ANSI American National Standards Institute C# C-Sharp DOS Disk Operating System FPGA Field Programmable Gate Array GALS Gerador de Analisadores Léxicos e Sintáticos KCPSM3 Constant (K) Coded Programmable State Machine LCD Liquid Crystal Display PC Program Counter PCCOMP PicoBlaze C Compiler PROM Programmable Read-Only Memory RAM Random Access Memory RISC Reduced Instruction Set Computer ROM Read-Only Memory TCC Trabalho de Conclusão de Curso VHDL Hardware Description Language
v
LISTA DE FIGURAS
Figura 1. Blocos funcionais do microcontrolador PicoBlaze ............................................................ 7
Figura 2. Fluxo de projeto do PicoBlaze ........................................................................................ 13
Figura 3. Etapas realizadas em um compilador .............................................................................. 21
Figura 4. Código de três endereços ................................................................................................ 24
Figura 5. Declaração para o comando if ......................................................................................... 32
Figura 6. Declaração do comando while ........................................................................................ 33
Figura 7. Tradução de expressões para notação de três endereços: (a) lógicas; (b) numéricas ......... 34
Figura 8. Diagrama de casos de uso ............................................................................................... 38
Figura 9. Definições regulares da linguagem ................................................................................. 40
Figura 10. Definição dos tokens ..................................................................................................... 41
Figura 11. Especificação sintática da linguagem ............................................................................ 42
Figura 12. Triplas: (a) estrutura; (b) programa ............................................................................... 47
Figura 13. Tela inicial do sistema .................................................................................................. 49
Figura 14. Menu File ..................................................................................................................... 49
Figura 15. Menu Edit ..................................................................................................................... 50
Figura 16. Menu Build................................................................................................................... 50
Figura 17. Menu Debug ................................................................................................................. 51
Figura 18. Depuração código assembly .......................................................................................... 52
Figura 19. Fluxo de projeto do PicoBlaze ...................................................................................... 52
Figura 20. Placa de prototipação Spartan-3 .................................................................................... 53
vi
LISTA DE TABELAS
Tabela 1. Conjunto de instruções do PicoBlaze .............................................................................. 10
Tabela 2. Tipos de dados suportados pelo PCCOMP ..................................................................... 16
Tabela 3. Conversão entre tipos realizada pelo PCCOMP .............................................................. 16
Tabela 4. Estruturas de controle suportadas pelo PCCOMP ........................................................... 17
Tabela 5. Número de instruções assembly ..................................................................................... 19
Tabela 6. Descrição dos arquivos fornecidos pelo Dalton-Project .................................................. 19
Tabela 7. Quádruplas ..................................................................................................................... 24
Tabela 8. Triplas ............................................................................................................................ 25
Tabela 9. Notação pós-fixa ............................................................................................................ 26
Tabela 10. Instruções de comparação, saltos e lógicas do PicoBlaze .............................................. 34
Tabela 11. Número de instruções assembly .................................................................................... 54
vii
RESUMO
SALVADOR, Farias Caroline. Compilador PicoBlaze C. Itajaí, 2009. 148. 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í, 2009. O microcontrolador PicoBlaze é um soft-core fornecido pela empresa Xilinx e pode ser otimizado em algumas de suas famílias de FPGA (Field Programmable Gate Array). Ele é desenvolvido em linguagem de descrição de hardware e foi projetado para ser usado em aplicações que realizam tarefas dedicadas como protocolos de comunicação implementados em máquinas de estados. Integrar um microcontrolador em uma FPGA oferece como vantagens a redução de espaço ocupado em silício, custo de desenvolvimento e a possibilidade de migrar o mesmo para novos FPGAs, eliminando a criação de produtos obsoletos. Apesar de o microcontrolador PicoBlaze possuir um conjunto de ferramentas que auxiliam o programador no desenvolvimento de projetos, a linguagem assembly ainda é utilizada. Atualmente existe apenas uma ferramenta para programação em linguagem de alto nível, porém esta apresenta várias restrições e limitações. Neste contexto, este TCC (Trabalho de Conclusão de Curso) teve como objetivo desenvolver um compilador C integrado com uma interface gráfica disponibilizando ao programador uma ferramenta de programação em linguagem de alto nível onde as aplicações podem ser desenvolvidas e testadas. Os testes realizados com a ferramenta indicaram que ela não possui erros e nem as limitações apresentadas pela ferramenta concorrente. Espera-se que a ferramenta gerada por este trabalho facilite o desenvolvimento e a validação de aplicações para o microcontrolador PicoBlaze, oferecendo como vantagens a redução do tempo, custo e complexidade de um projeto. Palavras-chave: Linguagem de Montagem. Compiladores. Microcontroladores.
viii
ABSTRACT
The PicoBlaze microcontroller is a soft-core provided by Xilinx and can be optimized in some of the
families of FPGA (Field Programmable Gate Array). He is developed using a hardware description
language to be used in applications that perform tasks such as dedicated communication protocols
implemented as finite state machines. Integrate a microcontroller in an FPGA offers advantages
such as the reduction of space occupied in silicon, cost of development and the opportunity of
migration for new FPGAs, eliminating obsolete products creation. Despite PicoBlaze
microcontroller be supplied with a set of tools that help the developer in the project development,
the assembly language is still used. Currently there is only one compiler for programming in high-
level language, but it has several restrictions and limitations. Considering this context, this
monography aims at developing a C compiler integrated with a graphical interface that will
provide a tool for programming in high-level language and an interface where the applications can
be tested. It is desired to provide a tool that facilitates the development and validation of
applications for PicoBlaze, offering benefits such as reducing the time, cost and complexity of a
project.
Keywords: Assembly Language. Compilers. Microcontrollers.
1 INTRODUÇÃO
O microcontrolador PicoBlaze é um soft-core fornecido pela empresa Xilinx para ser
otimizado em algumas de suas famílias de FPGA como: ProTM, Spartan e Virtex. Ele é
disponibilizado como código fonte sintetizável escrito em VHDL (Hardware Description Language
– Linguagem de Descrição de Hardware) e projetado para ser usado em projetos que realizam
tarefas dedicadas como protocolos de comunicação implementados em máquinas de estados. A
grande vantagem de se ter um microcontrolador integrado em uma FPGA é a redução de espaço
ocupado em silício, custo de desenvolvimento e a possibilidade de migrar o mesmo para novos
FPGAs, eliminando a criação de produtos obsoletos.
Para Souza (2003), o microcontrolador pode ser definido como um “pequeno” componente
eletrônico, dotado de uma “inteligência” programável, utilizado no controle de periféricos como
leds, botões e LCD (Liquid Crystal Display - Display de Cristal Líquido) e integra basicamente um
processador, memórias RAM (Random Access Memory – Memória de Acesso Aleatório) e ROM
(Read-Only Memory – Memória Somente de Leitura) e entrada/saída em um único chip.
Atualmente, o processo de desenvolvimento de aplicações para o microcontrolador
PicoBlaze envolve o uso do montador pBlazeIDE, fornecido pela empresa de engenharia
Mediatronix e um simulador gráfico do conjunto de instruções e código fonte VHDL fornecido pela
Xilinx.
Apesar de o microcontrolador PicoBlaze possuir um conjunto de ferramentas disponíveis
para o desenvolvimento de aplicações, os programadores ainda dependem de programação
assembly, o que dificulta o desenvolvimento e estende o tempo de projeto, sendo que a única
ferramenta disponível para programação em linguagem de alto nível, o PCCOMP (PicoBlaze C
Compiler – Compilador C PicoBlaze), apresenta diversos problemas e restrições que foram alvo de
análise neste trabalho.
Dentro deste contexto, este trabalho desenvolveu um compilador C integrado com uma
interface gráfica para o microcontrolador PicoBlaze, disponibilizando ao programador uma
ferramenta para programação em linguagem de alto nível e interface de testes.
Compiladores, conforme Louden (2004), são programas de computador que traduzem de
uma linguagem para outra. Um compilador recebe como entrada um programa escrito em
2
linguagem de alto nível, como C e C++, e produz o código objeto equivalente ao programa.
Tradicionalmente, um compilador é composto pelas etapas de análise léxica, análise sintática,
análise semântica e por um gerador de código, e cada uma das etapas realiza uma função específica.
O compilador proposto utilizou o GALS (gerador de analisadores léxicos e sintáticos) para
gerar as etapas de análise léxica e análise sintática, teve a análise semântica e a geração de código
implementada em linguagem de programação C# (C-Sharp) e gerou um arquivo de saída contendo
código assembly que foi utilizado pelo montador KCPSM3 (Constant (K) Coded Programmable
State Machine – Constante (K) Programável Codificada para Máquinas de Estados) para a geração
do bloco de memória de programa do microcontrolador. Já a interface gráfica possibilitou realizar
testes com os pinos de entrada e saída, banco de registradores, memória de dados e com a pilha
CALL/RETURN.
O arquivo de saída gerado pelo compilador foi utilizado como arquivo de entrada do
montador KCPSM3, o qual consiste de um executável DOS (Disk Operating System – Sistema
Operacional em Disco) que é responsável por gerar o bloco de memória de programa do
microcontrolador. Este montador recebeu como entrada um arquivo contendo a descrição em
assembly de uma aplicação e gerou como saída um arquivo VHDL com a descrição da memória. O
montador KCPSM3 é fornecido pela Xilinx juntamente com a descrição do microcontrolador
PicoBlaze e o JTAG Loader Programs, utilizado para regravar somente a memória de programa no
FPGA.
Ainda envolvido no contexto deste trabalho, esta à parceria estabelecida entre o Mestrado de
Computação Aplicada e a Empresa Intelbras que utiliza frequentemente este microcontrolador em
seus produtos. Dessa forma, este trabalho buscou contribuir na consolidação de uma parceria entre
Universidade e Empresa, promovendo inovação tecnológica aplicada à indústria.
1.1 PROBLEMATIZAÇÃO
1.1.1 Formulação do Problema
Os programadores que desenvolvem aplicações para o microcontrolador PicoBlaze ainda
dependem da programação assembly. O compilador PCCOMP é a única ferramenta disponível para
programação em linguagem de alto nível, no entanto apresenta diversos problemas e não oferece
interface para testes.
3
Outro problema está na incompatibilidade entre os dois montadores disponíveis. O montador
pBlazeIDE permite a depuração do código assembly por meio de interface, porém a sintaxe do
código assembly suportado por ele é diferente da sintaxe suportada pelo montador KCPSM que é o
responsável por gerar a memória de programa do PicoBlaze.
Apesar de o montador pBlazeIDE realizar a importação do código assembly suportado pelo
montador KCPSM, esta importação na maioria das vezes é feita de maneira incorreta o que dificulta
e prolonga a depuração da aplicação.
1.1.2 Solução Proposta
A solução proposta por este projeto foi desenvolver um compilador C para o
microcontrolador PicoBlaze integrado com uma interface gráfica de testes para a verificação do
comportamento da memória de dados, banco de registradores, pilha CALL/RETURN e pinos de
entrada e saída durante a depuração do código. O arquivo de saída gerado pelo compilador contém
código assembly compatível com o montador KCPSM.
1.2 OBJETIVOS
1.2.1 Objetivo Geral
O objetivo geral desse trabalho foi desenvolver um compilador C integrado com uma
interface gráfica para o microcontrolador PicoBlaze disponibilizando ao programador uma
ferramenta para programação em linguagem de alto nível e interface de testes.
1.2.2 Objetivos Específicos
Os objetivos específicos desse projeto foram:
• Pesquisar e documentar conceitos sobre compiladores, em especial a etapa de geração de
código;
• Documentar a arquitetura e o conjunto de instruções do microcontrolador PicoBlaze;
• Estudar e indicar as particularidades do módulo KCPSM3;
• Analisar e indicar os problemas do compilador PCCOMP;
4
• Implementar e disponibilizar uma ferramenta para programação em linguagem de alto
nível e interface para testes de aplicações;
• Testar e validar o arquivo de saída gerado pelo compilador em protótipo físico; e
• Documentar e divulgar o projeto.
1.3 Metodologia
A metodologia adotada neste projeto é composta por três etapas. Na primeira etapa foi
realizado o estudo sobre a arquitetura, o conjunto de instruções e o ambiente de desenvolvimento do
microcontrolador PicoBlaze, a elaboração de testbenchs para a análise do compilador PCCOMP e
estudo sobre as características e técnicas de projeto de compiladores.
Na segunda etapa foi realizada a modelagem do sistema que compreendeu a análise de
requisitos, a elaboração do diagrama de casos de uso e seus cenários e o desenvolvimento dos
protótipos de tela do sistema. Ainda na etapa de modelagem foi feita a definição das expressões
regulares, dos tokens e da gramática do compilador.
Por fim, na última etapa foi realizado o desenvolvimento do compilador que envolveu a
definição dos aspectos semânticos utilizados na implementação, a documentação da representação
escolhida para a geração do código intermediário do compilador e as políticas adotadas para
alocação de memória e registradores. Ainda nesta etapa realizou-se a validação do código assembly
gerado pelo compilador e a documentação dos resultados obtidos.
1.4 Estrutura do trabalho
Este documento está dividido em quatro capítulos. O Capítulo 1, Introdução, apresentou
uma visão geral sobre o projeto que será desenvolvido e seus objetivos. O Capítulo 2,
Fundamentação Teórica, apresenta a etapa de estudo, onde foi documentada a revisão bibliográfica
dos temas abordados neste projeto. O Capítulo 3, Projeto, descreve a análise e projeto do sistema
desenvolvido, apresenta os protótipos de tela do sistema e a definição da gramática. O Capítulo 4,
Desenvolvimento, apresenta a documentação das decisões de projeto que foram tomadas na etapa
de implementação do compilador, a validação do código assembly gerado e as limitações do
compilador. O Capítulo 5, Conclusões, descreve os resultados obtidos e trabalhos futuros. O projeto
também inclui o apêndice A que contém o código fonte dos testbenchs desenvolvidos, apêndice B,
onde se encontra a especificação sintática da linguagem suportada pelo compilador e o código fonte
5
do analisador semântico e o apêndice C que contém os arquivos VHDL da memória de programa do
microcontrolador PicoBlaze gerados a partir da compilação das aplicações do Dalton-Project no
compilador desenvolvido na etapa de validação.
2 FUNDAMENTAÇÃO TEÓRICA
Este capítulo apresenta a revisão bibliográfica sobre os assuntos abordados neste projeto. A
Seção 2.1 apresenta a descrição detalhada da arquitetura, do conjunto de instruções e do fluxo de
projeto do microcontrolador PicoBlaze, envolvendo também o estudo do módulo KCPSM3. A
Seção 2.2 apresenta as características do PCCOMP e os resultados da sua análise, que foi realizada
com o auxilio de testbenchs desenvolvidos manualmente. A Seção 2.3 apresenta a descrição das
etapas realizadas por um compilador. As etapas de análise léxica, sintática e semântica são vistas de
forma sucinta, pois estes temas já foram vistos durante o curso. Esta Seção também contém a
descrição das etapas de geração de código intermediário e geração de código final, que descreve os
métodos de alocação e atribuição de registradores, cálculos de atribuição de endereço, algoritmos de
estruturas de controle e representação das expressões lógicas.
2.1 Microcontrolador PicoBlaze
O microcontrolador PicoBlaze é um soft-core fornecido pela empresa Xilinx e pode ser
sintetizado por algumas de suas famílias de FPGA como: ProTM, Spartan e Virtex.
Os microcontroladores são dispositivos que possuem basicamente um processador, memória
e interface. Este tipo de dispositivo se limita a executar uma única tarefa de maneira contínua e não
realiza tratamento de erros (MORIMOTO, 2007).
O conjunto de instruções do microcontrolador PicoBlaze é do tipo RISC (Reduced
Instruction Set Computer – Computador com um Conjunto Reduzido de Instruções) e processa
dados de 8 bits. Seu código fonte é descrito em VHDL, que é uma linguagem de alto nível utilizada
para descrever comportamentos e funcionalidades de um circuito (D’AMORE, 2005).
O grande diferencial do PicoBlaze está na sua portabilidade, pois seu núcleo pode ser
migrado para novos FPGAs, descartando a criação de produtos obsoletos. A integração do
PicoBlaze em uma FPGA também apresenta como vantagens a redução do espaço ocupado em
silício e custo de desenvolvimento (CHAPMAN, 2008).
Segundo Hamblen e Furman (2002), FPGA é um circuito composto por um grande número
de elementos lógicos programáveis ou células. Estes elementos lógicos são interconectados por uma
matriz de trilhas condutoras e switches programáveis.
7
O núcleo do PicoBlaze é totalmente incorporado ao FPGA alvo e não necessita de recursos
externos, tornando-o extremamente flexível. As suas funcionalidades básicas podem ser facilmente
ampliadas devido ao grande número de pinos de entrada e saída que o microcontrolador contém.
2.1.1 Características do PicoBlaze
O microcontrolador PicoBlaze é composto por 16 registradores, uma ALU (Arithmetic
Logic Unit – Unidade Lógica Aritmética) e seus flags de sinalização, memória RAM, memória
PROM (Programmable Read-only Memory – Memória Programável só de Leitura), pinos de
entrada e saída, pilha CALL/RETURN e por um PC (Program Counter – Contador de Programa).Os
blocos funcionais que compõe o PicoBlaze são apresentados na Figura 1 (CHAPMAN, 2008).
Figura 1. Blocos funcionais do microcontrolador PicoBlaze
Fonte: Chapman (2008).
As próximas sessões apresentam a descrição detalhada de cada bloco funcional que compõe
o PicoBlaze.
Registradores de Uso Geral
O PicoBlaze possui 16 registradores para uso geral de 1 byte cada e são nomeados de S0 á
SF, sendo que nenhum registrador é reservado para operações especiais ou possui prioridade.
Também não há nenhum registrador dedicado, o resultado de cada operação é computado no
registrador especificado.
8
Memória PROM
O PicoBlaze armazena até 1.024 instruções de 18 bits. As instruções são compiladas e
carregadas automaticamente durante o processo de configuração da FPGA.
Memória RAM
O PicoBlaze possui um bloco de memória RAM de 64 posições de 1 byte cada para uso
geral. A memória RAM pode ser endereçada diretamente por uma constante ou indiretamente por
um registrador. Seu acesso é feito através de instruções de leitura e escrita.
A instrução de escrita escreve o conteúdo de um registrador em um endereço da memória
RAM. A instrução de leitura lê um endereço da memória RAM e armazena o dado lido em um
registrador. Estas duas operações permitem que um número maior de variáveis seja utilizado,
liberando os pinos para trabalhar como entrada e saída reais.
ALU
A unidade lógica aritmética executa as seguintes operações:
• Operações aritméticas como soma e subtração;
• Operações lógicas AND, OR e XOR;
• Operações aritméticas de comparação e teste bit a bit; e
• Operações de deslocamento e rotação.
Todas as operações são executadas utilizando um operador fornecido por qualquer
registrador (sx). O resultado é armazenado no mesmo registrador especificado. Se uma instrução
necessitar de um segundo operando, este será um segundo registrador (sy) ou uma constante
imediata de 8 bits.
Flags da ALU
As operações realizadas pela ALU afetam os flags ZERO e CARRY. O flag ZERO indica
que o resultado da última operação executada foi zero. Já o flag CARRY pode assumir várias
condições, dependendo da última instrução executada.
A ALU também possui o flag INTERRUPT_ENABLE, que é utilizado para habilitar e
desabilitar interrupções externas.
9
Pinos de Entrada e Saída
O PicoBlaze possui 256 pinos e entrada e 256 de saída e todos são bidirecionais, ou seja,
todos eles podem trabalhar tanto com entrada como saída de dados.
O PORT_ID armazena os endereços dos pinos. Quando uma operação de entrada é
realizada, o dado do pino IN_PORT é lido e armazenado em um registrador. Já na operação de
saída, o conteúdo de um registrador é escrito no pino OUT_PORT.
Pilha CALL/RETURN
A pilha suporta até 31 endereços de instruções. Ela é implementada como um buffer cíclico
e quando está cheia sobrescreve o valor mais antigo. Isso ocorre porque não existem instruções para
controlar a pilha ou o seu ponteiro.
PC
A função do contador de programa é apontar para a próxima instrução que será executada. O
PC é incrementado automaticamente para a próxima instrução logo após a instrução corrente ser
executada. Apenas as instruções de salto, eventos de interrupção e reset modificam o seu
comportamento. O PC não pode ser alterado diretamente pela aplicação.
Interrupção
O PicoBlaze possui uma entrada opcional de interrupção que permite a manipulação
assíncrona de eventos externos, no entanto, o ideal é sincronizar todas as entradas do
microcontrolador com a entrada do clock. O tempo de resposta de uma interrupção consome cinco
ciclos do clock.
Reset
O PicoBlaze é imediatamente resetado depois da conclusão do processo de configuração da
FPGA. Após a configuração ser realizada, a entrada de reset configura o processador para o seu
estado inicial. O PC é restaurado para apontar para o endereço zero da memória de programa, os
flags são zerados, as interrupções desabilitadas e a pilha restaurada. Os dados armazenados na
memória RAM e no banco de registradores não são afetados pelo reset.
10
Controle de Fluxo do Programa
A sequência padrão da execução de um programa no PicoBlaze pode ser modificada
utilizando instruções condicionais e incondicionais de salto dentro do fluxo do programa. A
instrução JUMP especifica um endereço absoluto dentro do espaço de memória de programa. Já as
instruções CALL e RETURN são utilizadas em seções de códigos de sub-rotinas. Estas instruções
usam a pilha que armazena automaticamente o endereço inicial de uma sub-rotina e o endereço de
retorno.
A interrupção é outro evento que pode causar alteração no fluxo do programa. Quando uma
interrupção é ativada, o PC armazena seu valor atual na pilha CALL/RETURN, permitindo que o
endereço do vetor de interrupção seja armazenado nele. Para retornar ao ponto da rotina que estava
sendo executado no momento da interrupção, utiliza-se a instrução RETURNI (CHAPMAN, 2008).
Conjunto de Instruções
O conjunto de instruções que o hardware do PicoBlaze é capaz de executar e a descrição de
cada uma delas é apresentada na Tabela 1.
Tabela 1. Conjunto de instruções do PicoBlaze
Instrução Descrição JUMP aaa Salto incondicional para o endereço aaa. JUMP Z, aaa Se o flag ZERO estiver setado (ZERO=1), salta para o endereço aaa. JUMP NZ, aaa Se o flag ZERO não estiver setado (ZERO=0), salta para o endereço aaa. JUMP C, aaa Se o flag CARRY estiver setado (CARRY=1), salta para o endereço aaa. JUMP NC, aaa Se o flag CARRY não estiver setado (CARRY=0), salta para o endereço
aaa. CALL aaa Chamada incondicional da sub-rotina do endereço aaa. CALL Z, aaa Se o flag ZERO estiver setado (ZERO=1), a sub-rotina do endereço aaa é
chamada. CALL NZ, aaa Se o flag ZERO não estiver setado (ZERO=0), a sub-rotina do endereço aaa
é chamada. CALL C, aaa Se o flag CARRY estiver setado (CARRY=1), a sub-rotina do endereço aaa
é chamada. CALL NC, aaa Se o flag CARRY não estiver setado (CARRY=0), a sub-rotina do
endereço aaa é chamada. RETURN Retorno incondicional para sub-rotina. RETURN Z Se o flag ZERO estiver setado (ZERO=1), retorna para a sub-rotina. RETURN NZ Se o flag ZERO não estiver setado (ZERO=0), retorna para a sub-rotina. RETURN C Se o flag CARRY estiver setado (CARRY=1), retorna para a sub-rotina. RETURN NC Se o flag CARRY não estiver setado (CARRY =0), retorna para a sub-
rotina. ADD sx, kk Soma o conteúdo do registrador sx com a constante kk (sx->sx+kk).
11
ADD sx, sy Soma o conteúdo do registrador sx com o conteúdo do registrador sy. ADDY sx, kk Soma o conteúdo do registrador sx com a constante kk e o flag CARRY
(sx->sx+kk+CARRY). ADDY sx, sy Soma os conteúdos dos registradores sx, sy e o flag CARRY (sx-
>sx+sy+CARRY). SUB sx, kk Subtrai à constante kk do conteúdo do registrador sx (sx->sx-kk). SUB sx, sy Subtrai do conteúdo do registrador sx o conteúdo do registrador sy (sx-
>sx-sy). SUBCY sx, kk Subtrai do conteúdo do registrador sx a constante kk e o valor do flag
CARRY (sx->sx-kk-CARRY). SUBCY sx, sy Subtrai do conteúdo do registrador sx o conteúdo do registrador sy e o
valor do flag CARRY (sx->sx-sy-CARRY). COMPARE sx, kk Compara o conteúdo do registrador sx com a constante kk. Se sx=kk o flag
ZERO é setado (ZERO=1), se sx<kk o flag CARRY é setado (CARRY=1). COMPARE sx, sy Compara o conteúdo do registrador sx com o conteúdo do registrador sy.
Se sx=sy o flag ZERO é setado (ZERO=1), se sx<sy o flag CARRY é setado (CARRY=1).
RETURNI ENABLE
Retorna para a rotina de serviço de interrupção. Reativa a interrupção.
RETURNI DISABLE
Retorna para a rotina de serviço de interrupção. Desativa permanentemente a interrupção.
ENABLE INTERRUPT
Habilita a entrada de interrupção.
DISABLE INTERRUPT
Desabilita a entrada de interrupção.
LOAD sx, kk Carrega a constante kk no registrador sx (sx<-kk). LOAD sx, sy Carrega o registrador sy no registrador sx (sx<-sy). AND sx, kk Operação lógica bit a bit entre a constante kk e o registrador sx (sx<-sx
AND kk). AND sx, sy Operação lógica bit a bit entre o registrador sX e o registrador sy (sx<-sx
AND sy). OR sx, kk Operação lógica bit a bit entre a constante kk e o registrador sx (sx<-sx OR
kk). OR sx, sy Operação lógica bit a bit entre o registrador sx e o registrador sy (sx<-sx
OR sy). XOR sx, kk Operação lógica bit a bit entre a constante kk e o registrador sx (sx<-sx
XOR kk). XOR sx, sy Operação lógica bit a bit entre o registrador sx e o registrador sy (sx<-sx
XOR sy). TEST sx, kk Operação lógica bit a bit entre um registrador e uma constante. O
registrador não é afetado. Se todos os bits da operação lógica forem iguais á zero, o flag ZERO é setado. Se um dos bits da operação lógica for igual a um, o flag CARRY é setado.
TEST sx, sy Operação lógica bit a bit entre dois registradores. Os registradores não são afetados. Se todos os bits da operação lógica forem iguais á zero, o flag ZERO é setado. Se um dos bits da operação lógica for igual a um, o flag CARRY é setado.
STORE sx, ss Escreve na memória RAM o conteúdo do registrador sx no endereço especificado pela constante ss.
12
STORE sx, (sy) Escreve na memória RAM o conteúdo do registrador sx no endereço especificado pelo registrador sy.
FETCH sx, ss Escreve no registrador sx o conteúdo da memória RAM que se encontra no endereço especificado pela constante ss.
FETCH sx, (sy) Escreve no registrador sx o conteúdo da memória RAM que se encontra no endereço especificado pelo registrador sy.
SR0 sx Desloca um bit para a direita. O bit menos significativo, bit 0, é armazenado no flag CARRY e o bit mais significativo, bit 7, recebe ‘0’. Se todos os bits do resultado forem iguais a zero, o flag ZERO é setado, caso contrário ele é zerado.
SR1 sx Desloca um bit para a direita. O bit menos significativo, bit 0, é armazenado no flag CARRY e o bit mais significativo, bit 7, recebe ‘1’.O flag ZERO sempre estará zerado, pois o resultado da operação nunca apresentará todos os bits em zero.
SRX sx Operação de deslocamento para a direita. O bit mais significativo, bit 7, é replicado, após o deslocamento ele é copiado de volta para o bit 7. (sx<-{sx[7], sx[7:1]}) CARRY<-sx[0].
SRA sx Desloca os bits para a direita, incluindo o CARRY. O CARRY recebe o bit 0 do registrador sx e o bit 7 do registrador sx recebe o CARRY.
RR sx Desloca os bits para a direita. O bit menos significativo, bit 0, é armazenado na flag CARRY e no bit mais significativo do registrador sx.
SL0 sx Desloca um bit para a esquerda. O bit mais significativo, bit 0, é armazenado no flag CARRY e o bit menos significativo, bit 7, recebe ‘0’. Se todos os bits do resultado forem iguais a zero, o flag ZERO é setado, caso contrário ele é zerado.
SL1 sx Desloca um bit para a esquerda. O bit mais significativo, bit 0, é armazenado no flag CARRY e o bit menos significativo, bit 7, recebe ‘1’. O flag ZERO sempre estará zerado, pois o resultado da operação nunca apresentará todos os bits em zero.
SLX sx Operação de deslocamento para a esquerda. O bit menos significativo, bit 0, é replicado, após o deslocamento ele é copiado de volta para o bit 0. (sx<-{sx[6:0], sx[0]}) CARRY<-sx[7].
SLA sx Desloca os bits para a esquerda, incluindo o CARRY. O CARRY recebe o bit 7 do registrador sx e o bit 0 do registrador sx recebe o CARRY.
RL sx Desloca os bits para a esquerda. O bit mais significativo, bit 7, é armazenado na flag CARRY e no bit menos significativo do registrador sx.
INPUT sx, pp Lê o valor da porta de entrada especificada por pp e armazena no registrador sx.
INPUT sx, (sy) Lê o valor da porta de entrada apontada pelo registrador sy e armazena no registrador sx.
OUTPUT sx, pp Escreve o conteúdo do registrador sx na porta de saída especificada por pp. OUTPUT sx, (sy) Escreve o conteúdo do registrador sx na porta de saída apontada pelo
registrador sy.
Fonte: Chapman (2008).
13
2.1.2 Ambiente de Desenvolvimento
Atualmente, o PicoBlaze é apoiado por um conjunto de ferramentas de desenvolvimento que
inclui o montador pBlazIDE, fornecido pela empresa de engenharia Mediatronix e um simulador
gráfico do conjunto de instruções e código fonte VHDL fornecido pela Xilinx.
A Xilinx também fornece o pacote KCPSM que contém o código fonte do PicoBlaze, um
montador e um utilitário que realiza a modificação da memória de programa sem a necessidade de
recompilar todo o projeto. A última versão disponibilizada é o pacote KCPSM3 que será utilizado
neste projeto.
O fluxo de projeto do PicoBlaze, desde o desenvolvimento do programa até a prototipação
em FPGA, é apresentado na Figura 2.
Figura 2. Fluxo de projeto do PicoBlaze
O montador pBlazIDE auxilia o programador na etapa de desenvolvimento, identificando
erros de sintaxe e provê uma interface de depuração do programa assembly. Durante a depuração
passo a passo do código, é possível observar como o banco de registradores, memória de dados,
flags do processador, interrupções e pinos de entrada e saída se comportam.
Na etapa desenvolvimento o programador precisa decidir qual sintaxe irá utilizar para
implementar o programa, pois existe diferença entre a sintaxe suportada pelo pBlazIDE e pelo
montador KCPSM.
Se a intenção do desenvolvedor for gravar o programa na memória do PicoBlaze, ele
utilizará a sintaxe do conjunto de instruções do KCPSM. O programa desenvolvido é utilizado
14
como arquivo de entrada do montador KCPSM que traduz o código assembly e inclui o mesmo em
um template da memória de programa, gerando como saída um arquivo VHDL.
O arquivo gerado pelo montador KCPSM deve ser incluído no fluxo de projeto do
PicoBlaze e sintetizado no simulador ISE. Com o simulador é possível compilar, sintetizar e gravar
o PicoBlaze na FPGA. Também é possível realizar testes através de diagramas de formas de onda
para validar a sintetização do microcontrolador (CHAPMAN, 2003).
2.2 PCCOMP
O PCCOMP, desenvolvido por Francesco Poderico, é um compilador C para as versões dos
módulos KCPSM2 e KCPSM3 do PicoBlaze fornecidos pela Xilinx. O PCCOMP é compatível com
o sistema operacional Windows e foi testado pelo desenvolvedor no Windows XP e no Windows
me. Ele é gratuito e está disponível para download na internet.
Este é o único compilador C para o PicoBlaze disponível e sua análise servirá de base para o
desenvolvimento deste projeto. Um dos objetivos deste projeto é criar um compilador que supra as
falhas que o PCCOMP apresenta e disponibilizar uma interface gráfica onde o desenvolvedor possa
validar suas aplicações de maneira mais eficiente e rápida.
Juntamente com o compilador é possível obter um manual escrito pelo desenvolvedor. Este
manual descreve o funcionamento do PCCOMP, porém várias particularidades só foram
descobertas durante a realização dos testes. O manual é a única fonte de informação sobre o
compilador PCCOMP. Problemas como declaração de variáveis e sintaxe da linguagem foram
algumas das características descobertas apenas por meio de testes.
Além da falta de documentação, outra dificuldade esta na baixa qualidade das mensagens de
erro do compilador, pois a compilação é realizada através de linha de comando e não é possível
verificar em qual trecho do código se encontra um erro quando a compilação não é realizada com
sucesso.
Limitações também são encontradas na depuração do código assembly gerado pelo
PCCOMP. Só é possível verificar se o código gerado funciona corretamente utilizando o montador
pBlazeIDE, onde o código gerado deve ser importado para o montador que, na maioria das vezes,
realiza essa importação de maneira incorreta, dificultando e prolongando a tarefa de depuração da
aplicação.
15
As próximas sessões irão apresentar as características do PCCOMP e os problemas
encontrados na etapa de compilação e depuração.
2.2.1 Características do PCCOMP
O compilador PCCOMP consiste de um executável DOS e a compilação do código fonte é
realizada através de linha de comando. Com ele é possível gerar código assembly para os módulos
KCPSM2 e KCPSM3, disponibilizados pela Xilinx, e inserir o código C comentado durante a
compilação, possibilitando ao desenvolvedor visualizar o código assembly gerado para cada
instrução C.
Após a compilação do código fonte, o PCCOMP gera como saída um arquivo com extensão
PSM contendo código assembly, que pode ser utilizado pelo montador fornecido pelo módulo
KCPSM para a geração da memória de programa do PicoBlaze.
Diretivas
A maioria das diretivas suportadas pelo PCCOMP segue o padrão ANSI (American National
Standards Institute – Instituto Nacional Americano de Padronização) para o C e são as seguintes:
• #asm #endasm: utilizada para incluir código assembly em qualquer trecho do programa;
• #include: utilizada para incluir cabeçalho de arquivo externo. Essa diretiva se diferencia
do padrão ANSI C, pois sua utilização no PCCOMP permite que o desenvolvedor
escreva um driver e o utilize em suas aplicações. O PCCOMP disponibiliza os
cabeçalhos spartan3.h e o sqrt.h;
• #define: utilizado para declarar valores constantes; e
• #ifdef, #ifndef, #else e #endif: são diretivas utilizadas para a compilação condicional.
Tipos de Dados
O PCCOMP suporta valores positivos e utiliza a representação em complemento de dois
para valores negativos. Os tipos disponíveis suportam dados de 8 e 16 bits e a faixa de valores que
cada tipo armazena estão descritos na Tabela 2.
16
Tabela 2. Tipos de dados suportados pelo PCCOMP
Tipo Faixa de valores Número de bits char -127… +128 8 bits int -32727… +32768 16 bits unsigned int 0... +65535 16 bits unsigned char 0... 255 8 bits
Fonte: Poderico (2005).
Ponteiros
Os ponteiros são utilizados pelo PCCOMP para realizar entrada e saída de dados nas portas
do PicoBlaze. Um ponteiro pode somente apontar para variáveis locais, globais e para arrays,
ponteiro para ponteiro não é suportado.
Arrays
O PCCOMP suporta apenas array unidimensional. Seu tamanho máximo é de 63 posições e
o índice deve ser declarado como char ou unsigned char.
Conversão entre Tipos
As possíveis conversões entre os tipos dos dados que o PCCOMP realiza são apresentadas
na Tabela 3:
Tabela 3. Conversão entre tipos realizada pelo PCCOMP
De Para char int char unsigned int unsigned char int unsigned char unsigned int
Fonte: Poderico (2005).
Estruturas de Controle
As estruturas de controle suportadas pelo PCCOMP estão listadas na Tabela 4.
17
Tabela 4. Estruturas de controle suportadas pelo PCCOMP
Laço de repetição Comando condicional FOR IF WHILE ELSE DO WHILE SWITCH
Fonte: Poderico (2005).
Interrupções
O PCCOMP possui suporte à interrupção e algumas condições precisam ser respeitadas:
• A rotina de interrupção deve ser escrita em assembly e apenas os registradores s0,
s1, s2, s3 devem ser usados.
• A interrupção deve ser declarada e definida como qualquer outra função.
• A declaração da rotina de interrupção deve respeitar a seguinte sintaxe: interrupt
nome_funcao (void).
Funções
As funções não podem receber como parâmetros nem ponteiros nem arrays e todas elas
precisam ser declaradas e definidas, ou seja, é necessário criar os protótipos das funções.
2.2.2 Análise
Na etapa de análise o conjunto de aplicações escritas em C disponibilizado pelo Dalton-
Project foi utilizado. O Dalton-Project é um projeto realizado no Departamento de Ciência da
Computação e Engenharia da Universidade da Califórnia, onde são desenvolvidos modelos
sintetizáveis descritos em VHDL de sistemas embarcados. Na página do projeto encontra-se o
conjunto de aplicações escritas em C que foi usado para validar o microcontrolador 8051
desenvolvido pelo projeto.
Este conjunto de aplicações disponibilizado pelo Dalton-Project também foi usado neste
projeto para a geração dos testbenchs utilizados para analisar e testar o compilador PCCOMP. Os
testbenchs consistem da tradução manual deste conjunto de aplicações para o assembly do
microcontrolador PicoBlaze.
18
Algumas alterações foram realizadas nas rotinas do Dalton-Project para implementar os
testbenchs. As declarações de variáveis passaram a ser globais para minimizar o tamanho da
aplicação, pois se trata da geração de código para um microcontrolador que possui 1Kbyte de
memória de programa e alteração de algumas atribuições, onde foi respeitado o tamanho máximo
dos dados que é de 8 bits.
Estes testbenchs foram validados utilizando o montador pBlazeIDE e comparados com o
assembly gerado pelo PCCOMP. Para tornar possível esta análise, algumas alterações tiveram que
ser realizadas nos códigos C para que o PCCOMP pudesse gerar o assembly. Em alguns testes o
código C não precisou ser alterado e foram compilados com sucesso, porém o assembly gerado não
executou corretamente.
Testes
Na etapa de testes todas as aplicações escritas em C do Dalton-Project, tanto os adaptados
como os originais, foram compiladas no PCCOMP e os problemas identificados foram:
• Declaração de variáveis locais: o PCCOMP gera código assembly para manipular as
variáveis locais e, na maioria das rotinas testadas, os cálculos de acesso a memória de
dados são incorretos, fazendo com que a rotina entre em loop infinito.
• Tipo de dados: o tipo inteiro possui 16 bits e ocupa duas posições da memória de dados.
O PCCOMP gera código para acessar e manipular esses dados e o mesmo erro de
cálculo que ocorre com variáveis locais, também acontece com as variáveis inteiras.
• Operador de comparação: o operador de comparação != (diferente) é suportado pelo
PCCOMP e compilado com sucesso, porém o assembly gerado não executa
corretamente esta operação.
• Inicialização de variáveis: o PCCOMP não suporta declaração e inicialização de
variáveis e/ou arrays em um único comando, tornando o código C mais extenso.
• Expressões aritméticas: não é possível utilizar expressões aritméticas no PCCOMP, cada
comando pode ter composto apenas por um operador e duas variáveis. Esta restrição
dificulta o desenvolvimento, exige um número maior de variáveis, torna o código C mais
extenso e bem próximo do assembly.
19
Dentre os problemas listados, o que ocorreu com maior frequência foi a declaração de
variáveis locais. Apenas as expressões aritméticas e declaração e inicialização de variáveis em um
único comando geram erro durante a compilação, os demais problemas não apresentam erros na
compilação e só ocorreram em alguns arquivos.
Além disso, ao analisar a quantidade de instruções geradas pelo compilador, é possível
identificar que ele não está gerando um código de boa qualidade em termos de performance. A
Tabela 5 ilustra o número de instruções assembly que foram geradas manualmente e o número de
instruções geradas pelo PCCOMP para cada arquivo C do Dalton-Project.
Tabela 5. Número de instruções assembly
Arquivo Assembly manual Assembly PCCOMP fib.c 37 instruções 207 instruções sqroot.c 73 instruções 198 instruções divmul.c 54 instruções 231 instruções negcnt.c 11 instruções 40 instruções sort.c 83 instruções 283 instruções xram.c 14 instruções 82 instruções cast.c 25 instruções 175 instruções gcd.c 23 instruções 79 instruções int2bin.c 33 instruções 87 instruções
Os testbenchs gerados manualmente, os arquivos C do Dalton-Project e os arquivos
assembly gerados pelo compilador PCCOMP se encontram no apêndice A. A Tabela 6 apresenta a
descrição de cada um dos arquivos utilizados nos testes.
Tabela 6. Descrição dos arquivos fornecidos pelo Dalton-Project
Arquivo Descrição fib.c
A aplicação fib.c calcula a sequência de Fibonacci. Ela possui um método principal que realiza apenas as chamadas para as métodos fib(), que realiza o calculo, e print(), que imprime o resultado.
sqroot.c
Esta aplicação possui apenas o método principal e realiza duas operações de multiplicação, soma os resultados das multiplicações e calcula a raiz quadrada do resultado da soma.
divmul.c
Composta apenas pelo método principal. Utiliza o laço de repetição FOR para incrementar uma variável e realiza operações de divisão, multiplicação e soma.
negcnt.c
Contém apenas o método principal e imprime números negativos dentro de um intervalo controlado pelo laço de repetição FOR.
sort.c
A aplicação sort.c executa a ordenação por inserção. O método principal contém apenas as chamadas para as funções sort(), que realiza a ordenação crescente dos dados de um vetor, e a print(), que
20
imprime o resultado. xram.c
Esta aplicação possui apenas o método principal que realiza o preenchimento de todas as posições da memória de dados utilizando um vetor e o laço de repetição FOR.
cast.c
Esta aplicação possui apenas o método principal. Ela realiza o deslocamento para a direita de um valor e imprime o resultado.
gcd.c
Possui apenas o método principal e utiliza o laço de repetição WHILE e comandos condicionais IF/ELSE para subtrair e imprimir os dados.
int2bin.c
A aplicação possui apenas o método principal. Ela utiliza o laço de repetição FOR, comandos condicionais IF/ELSE, realiza a operação de deslocamento para a direita e a operação lógica AND.
2.3 Compiladores
Compiladores são programas de computador que traduzem de uma linguagem para outra.
Um compilador recebe como entrada um programa escrito na linguagem-fonte e produz um
programa equivalente na linguagem-alvo. Geralmente, a linguagem-fonte é uma linguagem de alto
nível, como C ou C++, e a linguagem-alvo é um código objeto para a máquina alvo, ou seja, um
código escrito usando as instruções de máquina do computador no qual ele será executado
(LOUDEN, 2004, p.1).
Tradicionalmente, um compilador é composto por várias etapas e cada uma delas realiza
uma tarefa diferente. As etapas de análises léxica, sintática e semântica (front-end), analisam o
código fonte e geram uma representação intermediária do mesmo. Já a etapa de síntese (back-end),
utiliza a representação intermediária criada na fase de análise para gerar código alvo (AHO et al.,
2008). A Figura 3 apresenta as atividades realizadas pelo compilador.
21
Figura 3. Etapas realizadas em um compilador
Fonte: Adaptado de Ricarte (2008).
A análise léxica é responsável por ler os caracteres do programa fonte e agrupar os mesmos
em símbolos (tokens) que representam palavras reservadas, nomes de variáveis e procedimentos,
operadores e símbolos de pontuação que compõe uma linguagem.
Depois que todos os símbolos foram reconhecidos, a análise sintática verifica se a seqüência
de símbolos do programa fonte descreve comandos válidos e gera uma árvore sintática para
armazená-los, estes comandos podem ser uma expressão, uma operação ou uma atribuição.
Tendo a árvore sintática pronta, o compilador pode realizar a análise semântica, que utiliza a
árvore sintática para procurar incoerências nos comandos do programa fonte, o objetivo dessa fase é
encontrar variáveis não declaradas, tipos de operadores incompatíveis, entre outros (AHO et al.,
2008).
Após todas as análises serem realizadas e nenhum erro ser detectado, a etapa de geração de
código se encarrega de gerar um arquivo de saída contendo o código executável para determinada
máquina.
Esse arquivo de saída pode conter código assembly ou objeto, onde o código assembly
precisa ser processado por um montador para gerar código alvo e o código objeto, chamado de
programa objeto, que pode ser carregado na memória da máquina e executado pelo sistema
operacional.
22
2.3.1 Geração de Código Intermediário
A etapa de geração de código é considerada a mais complexa, pois é necessário levar em
consideração a arquitetura-alvo, o ambiente onde o código gerado será executado e o sistema
operacional da máquina-alvo caso a mesma o tenha (LOUDEN, 2004).
Por essa razão, a etapa de geração de código é, normalmente, dividida em fases como a
geração de código intermediário, otimização e geração de código assembly. No entanto, é possível
gerar código assembly a partir da árvore sintática, eliminando a geração de código intermediário,
porém se a intenção é desenvolver um compilador capaz de gerar código otimizado e eficiente, essa
etapa é indispensável.
Um compilador que implementa código intermediário, além de gerar código otimizado e
eficiente, apresenta várias vantagens. Com o código intermediário é possível representar
corretamente todas as expressões do código-fonte, pois sua estrutura é muito próxima do código
assembly, o que facilita sua implementação e, torna o compilador independente de arquitetura,
permitindo que o compilador seja direcionado para outra arquitetura-alvo (LOUDEN, 2004).
Tipicamente a etapa de geração de código intermediário ocorre sequencialmente à análise
sintática, contudo estas duas etapas podem ser combinadas e realizadas simultaneamente (AHO et
al., 2008).
Existem várias maneiras de implementar código intermediário e as duas notações mais
utilizadas são a notação de código de três endereços e a pós-fixa. A escolha de uma representação
varia de um compilador para outro.
2.3.1.1 Código de Três Endereços
A notação de código de três endereços representa a árvore sintática linearmente e sua
construção é baseada em dois conceitos: endereços e instruções. (LOUDEN, 2004).
Os conceitos, endereços e instruções, são a forma como a notação de três endereços
representa o programa fonte dentro de uma estrutura.
Segundo Aho et al.(2008), um endereço pode ser um nome que, durante a implementação, é
substituído por um apontador para a tabela de símbolos desse nome, uma constante ou um
temporário criado pelo compilador. Já uma instrução pode ser de atribuição, uma cópia indexada
23
ou não, desvios condicionais e incondicionais, chamadas de procedimento, atribuições de endereços
e apontadores.
A tabela de símbolos é uma estrutura de dados gerada pelo compilador usada para
armazenar informações sobre identificadores de variáveis, de parâmetros, de funções, de
procedimentos, entre outros. Sua construção é iniciada na etapa de análise léxica, quando os
identificadores da linguagem são reconhecidos, e sua função é auxiliar nas atividades da análise
semântica do código (PRICE; TOCANI, 2005; RICARTE, 2008).
Com base nesses conceitos, a implementação de código intermediário utilizando a notação
de código de três endereços é feita utilizando estruturas como matriz e lista encadeada que possuem
registros compostos por campos.
A estrutura escolhida para a implementação do código de três endereços representa
operações binárias com no máximo três variáveis, onde duas são reservadas para armazenar os
operadores e uma para armazenar o resultado da operação (RICARTE, 2008).
Quando uma expressão abrange diversas operações, é necessário realizar a decomposição da
mesma, criando subexpressões que respeitem a representação de operações binárias (RICARTE,
2008). Comumente o código de três endereços pode ser implementado utilizando triplas ou
quádruplas. A escolha da estrutura que será utilizada depende de como o compilador será
implementado e do conjunto de instruções da máquina alvo.
Quádruplas
Uma quádrupla é constituída pelos campos op (operação), arg1 (argumento 1), arg2
(argumento 2) e result (resultado), onde op contém um código interno para o operador, arg1 e arg2
são os operadores que podem representar constantes ou literais sem endereços de memória e result,
que recebe o resultado da operação e obrigatoriamente deve representar um endereço de memória
(LOUDEN, 2004; AHO et al., 2008).
Segundo Aho et al. (2008), algumas exceções podem ocorrer:
• Instruções com operadores unários não utilizam o arg2. Quando o comando executa uma
operação de cópia, o campo op recebe o operador de atribuição e na maioria das demais
operações a atribuição é implícita;
24
• Parâmetros não utilizam arg2 nem result; e
• Comandos condicionais e incondicionais colocam o rótulo de destino em result.
A Figura 4 apresenta o código de três endereços e a Tabela 7 as quádruplas para a atribuição
(a = b * - c + b * - c). É possível observar nas quádruplas da tabela 7 as instruções com operadores
unários (- c), neste caso o operador especial “menos” é utilizado para diferenciar instruções unárias
do operador binário em uma subtração como: (a - b) (AHO et al., 2008).
t1 = menos c t2 = b * t1 t3 = menos c t4 = b * t3 t5 = t2 + t4 a = t5
Figura 4. Código de três endereços
Fonte: Aho et al. (2008).
Tabela 7. Quádruplas
Op arg1 Arg2 Result Menos c t1 * b t1 t2 menos c t3 * b t3 t4 + t2 t4 t5 = t5 A
Fonte: Aho et al. (2008).
Nas quádruplas as atribuições geram cópias e cada subexpressão possui um temporário para
armazenar seu resultado. Quando uma expressão contém várias operações, a localização do seu
resultado final é descoberta após a execução de todas as suas subexpressões (AHO et al., 2008).
Triplas
Uma tripla é constituída por três campos: op (operador), arg1 (argumento 1) e arg2
(argumento 2). A diferença entre triplas e quádruplas esta na criação de temporários, uma vez que,
nas triplas, o resultado de uma operação é referenciado por apontadores que indicam sua posição na
estrutura ao invés de ser armazenado em um temporário (AHO et al., 2008).
A utilização de apontadores para os resultados nas triplas pode trazer vantagens ou
desvantagens, dependendo das tarefas que o projetista deseja implementar.
25
As vantagens de se utilizar apontadores para os resultados nas triplas estão na diminuição de
espaço ocupado pela sua estrutura e na eliminação de geração de temporários pelo compilador
(LOUDEN, 2004).
Já a grande desvantagem de se utilizar apontadores para resultados ocorre quando se deseja
realizar otimização de código. Nas triplas, quando uma instrução calcula um temporário e essa
instrução precisa ser movimentada, todas as referências para esse temporário também precisam ser
alteradas. Dessa forma as quádruplas são mais flexíveis, eliminando a necessidade de realizar
alterações em todas as quádruplas que utilizam o mesmo temporário quando uma instrução precisa
ser movimentada (AHO et al., 2008).
Porém existem as triplas indiretas que eliminam o problema de alteração das referencias e
torna a otimização de código tão eficiente quando nas quádruplas.
Nas triplas indiretas uma lista é utilizada para armazenar os apontadores das triplas. Em um
compilador que realiza otimização utilizando essa representação, a única estrutura que é rearranjada
quando uma instrução precisa ser movimentada é a lista, descartando a necessidade de alteração de
referencias na própria tripla (AHO et al., 2008). A Tabela 8 apresenta a tripla da atribuição (a = b
* - c + b * - c). Os valores entre parênteses, armazenados no campo arg2, são os apontadores para
os resultados das expressões.
Tabela 8. Triplas
apontador op arg1 arg2 0 menos c 1 * b (0) 2 menos c 3 * b (2) 4 + (1) (3) 5 = a (4)
Fonte: Aho et al. (2008).
2.3.1.2 Notação Pós-fixa
A notação pós-fixa, também conhecida como notação polonesa, utiliza o conceito de pilha
para representar os dados de uma expressão aritmética. Este tipo de representação armazena
primeiro os operandos da expressão e depois os operadores (RICARTE, 2008).
26
A representação intermediária utilizando a notação pós-fixa é muito eficiente na geração de
código para máquinas baseadas em pilha e seu atrativo é que ela dispensa o uso de parênteses nas
expressões. O que possibilita a eliminação de parênteses nas expressões é a estratégia pós-ordem
utilizada na varredura da árvore sintática (RICARTE, 2008).
O cálculo das expressões aritméticas representadas nessa notação segue os seguintes passos:
• Lê um token da árvore sintática;
• Verifica se esse token é um operando ou um operador;
• Se for um operando, empilha; e
• Se for um operador, desempilha dois operandos, realiza o calculo utilizando o operador e
empilha o resultado.
Os tokens são unidades básicas do texto do programa e cada token representa uma
informação. Eles podem representar um identificador, uma constante, uma cadeia de caracteres,
palavras reservadas da linguagem e operadores (PRICE; TOSCANI, 2005). A Tabela 9 apresenta
algumas expressões e sua representação pós-fixa.
Tabela 9. Notação pós-fixa
Expressão Notação pós-fixa (a+b)*c ab+c* a*(b+c) abc+* a+b*c abc*+
Fonte: Price e Toscani (2005).
2.3.2 Geração de Código
A geração de código é a ultima etapa realiza pelo compilador. A sua maior responsabilidade
é gerar código correto e garantir que todos os recursos disponíveis na máquina-alvo sejam utilizados
(AHO et al., 2008).
O gerador de código recebe como entrada uma representação intermediária do código fonte
que pode ser em notação de três endereços, representações de máquina virtual como a máquina de
pilha e representações lineares como a árvore sintática, gerando como saída código assembly (AHO
et al., 2008).
27
O processamento do código intermediário passa por três tarefas realizadas pelo gerador de
código: alocação e atribuição de registradores, seleção das instruções e escalonamento das
instruções. A complexidade na implementação das tarefas varia conforme a arquitetura da máquina-
alvo (AHO et al., 2008).
A tarefa de alocação e atribuição de registradores é responsável por atribuir as estruturas de
dados do código intermediário para os registradores, memória e pilha da máquina-alvo. Já a tarefa
de seleção de instruções realiza a tradução das instruções intermediárias para a linguagem da
máquina-alvo. Por fim, o escalonamento de instruções é responsável por identificar o ambiente de
execução do código como, por exemplo, a execução de rotinas (CRESPO, 1998).
O gerador de código usa uma rotina para cada regra encontrada no programa fonte. Estas
regras podem ser de alocação de registradores, cálculos de endereços, laços de repetição, entre
outros. Toda vez que uma regra é identificada a rotina apropriada é chamada e executada (BECK,
1993). O compilador que será desenvolvido neste projeto produzirá apenas código assembly e
utilizará esta técnica na geração de código intermediário.
2.3.2.1 Alocação e Atribuição de Registradores
Um dos problemas mais importantes a ser resolvido pelo gerador de código é decidir quais
variáveis serão armazenadas nos registradores e em quais registradores. As instruções que contém
suas variáveis armazenadas em registradores são significantemente menores e mais rápidas do que
aquelas que possuem variáveis armazenadas na memória (AHO et al., 2008).
A alocação de registradores pode ser feita tanto na etapa de geração de código intermediário
como pelo gerador de código.
Produzir a alocação de registradores na etapa de geração de código intermediário tem como
vantagem possibilitar sua reutilização por outras máquinas-alvo. No entanto, pode haver vantagens
realizar a alocação dos registradores após o código assembly ser gerado, pois várias instruções
podem ser combinadas e algumas variáveis podem ser eliminadas quando o compilador realiza
otimização de código (MOGENSEN, 2008).
Segundo Aho et al. (2008), a alocação de registradores geralmente esta dividida em dois
subproblemas:
28
• Alocação de registradores: etapa que seleciona o conjunto de variáveis que estarão
armazenadas em registradores em cada ponto do programa; e
• Atribuição de registradores: etapa que especifica em qual registrador uma determinada
variável residirá.
É aceitável reservar alguns registradores e utilizá-los para realizar cálculos, armazenar o
endereço do topo da pilha, entre outros. Esta reserva deve ser feita de maneira ponderada, pois isso
pode causar má distribuição na utilização dos registradores (AHO et al., 2008).
Para alocar os registradores que não estão reservados, o código intermediário pode ser
dividido em blocos básicos. Essa divisão possibilita o controle do armazenamento das variáveis em
cada ponto do programa.
O algoritmo que gera os blocos básicos recebe como entrada a sequência de instruções do
código intermediário e gera como saída uma lista de blocos básicos onde cada instrução pertence a
exatamente um bloco. Primeiramente, o algoritmo determina a primeira instrução de cada bloco
básico, chamada de líder, e segue a regra de que apenas a última instrução do código intermediário
nunca será líder (AHO et al., 2008).
Para Aho et al. (2008), as regras para encontrar as primeiras instruções de cada bloco básico
são:
• A primeira instrução do código intermediário é um líder;
• Qualquer instrução que seja alvo de um desvio condicional ou incondicional é um líder;
e
• Qualquer instrução subseqüente a um desvio condicional ou incondicional é líder.
Cada bloco básico possui um líder e todas as instruções, até a próxima instrução líder,
compõe seu escopo.
Todas as operações executadas em um programa devem ter seus operandos armazenados no
banco de registradores do processador. Durante a execução do programa é necessário realizar o
controle da atribuição de registradores para as variáveis de cada bloco básico.
29
Na entrada e na saída de cada bloco básico existem variáveis vivas, ou seja, variáveis que
são usadas por vários blocos. Segundo Mogensen (2008), algumas regras podem ser utilizadas para
determinar se uma variável esta viva:
• Se uma instrução utiliza o conteúdo de uma variável, esta variável deve estar viva no
início desta instrução;
• Se uma instrução atribui um valor a uma variável e esta variável não é um operando da
próxima instrução, ela é considerada uma variável morta, pois seu valor não é utilizado
neste momento;
• Se uma variável está viva no início de uma instrução, ela estará viva imediatamente após
o término da instrução anterior; e
• Se no final de uma instrução uma variável estiver viva e se esta instrução não atribuiu
nenhum valor para a variável, esta variável também estava viva no início da mesma
instrução.
No final da execução de cada bloco básico é necessário verificar quais variáveis não serão
utilizadas pelo próximo bloco e armazená-las na memória de dados e quais precisam estar vivas, ou
seja, quais devem permanecer no banco de registradores.
Além do controle de alocação e atribuição de registradores e das variáveis vivas, os blocos
básicos também precisam seguir um fluxo de execução entre eles. O fluxo de execução entre os
blocos é representado através de um grafo de fluxo. Este grafo é constituído por dois nós adicionais,
que indicam a entrada e a saída do grafo, e os demais nós pelos blocos básicos. As arestas deste
grafo determinam qual é a sequencia de execução entre os blocos (AHO et al., 2008).
Controlando o fluxo de execução dos blocos básicos, é possível realizar a atribuição global
de registradores. Esta atribuição permite que as variáveis usadas frequentemente sejam mantidas
consistentes nos limites de cada bloco básico, ou seja, armazenadas em registradores fixos durante
toda a execução do programa (AHO et al., 2008).
Manter um número fixo de registradores reservados para alocar variáveis globalmente é uma
estratégia para diminuir o acesso á memória de dados, porém é impossível reservar um número
exato de registradores, pois o número de variáveis vivas entre os blocos básicos pode variar.
30
Os registradores que não estão reservados, são utilizados pelas variáveis temporárias dos
blocos básicos. Durante a execução de um programa, provavelmente existirá algum ponto onde
todos os registradores estarão alocados. Neste caso é inevitável realizar o derramamento de
registradores.
O derramamento de registradores ocorre quando todos os registradores estão ocupados e é
necessário armazenar temporariamente os valores de alguns registradores para a alocação de novos
valores, permitindo que uma operação seja realizada (LOUDEN, 2004).
A tarefa de alocação e atribuição de registradores é complexa e possui várias etapas. Estas
etapas têm como objetivo utilizar, da melhor maneira possível, o banco de registradores e evitar ao
máximo gerar código de acesso á memória de dados.
Várias técnicas de otimização podem ser utilizadas para garantir melhor desempenho na
utilização do banco de registradores. Dentro do escopo deste projeto, esta será uma das etapas mais
importantes, pois se trata da alocação e atribuição de apenas 16 registradores.
2.3.2.2 Atribuição de Endereço
Esta tarefa realiza a atribuição de endereços para as variáveis do programa. Os endereços
podem ser atribuídos tanto na etapa de geração de código intermediário como na etapa de geração
de código final.
As variáveis do programa são identificadas apenas pelo seu nome e, normalmente o gerador
de código se encarrega de substituir esses nomes por endereços efetivos que pode ser um registrador
ou um endereço absoluto de memória para variáveis simples e endereços de deslocamento para
estruturas de dados (LOUDEN, 2004).
Existem várias situações que apenas atribuir um endereço a uma variável não é o suficiente,
é preciso realizar cálculos para localizar o endereço que se deseja alcançar. Estes cálculos devem
estar explícitos no código intermediário e são utilizados para a indexação de matrizes, estruturas de
dados constituídas por campos ou nomes e referências para ponteiros (LOUDEN, 2004).
Os cálculos de endereços variam conforme a notação utilizada na etapa de geração de código
intermediário. Cada notação possui uma estrutura diferente para representar o código, as estruturas
31
podem ser uma pilha ou uma lista e, por esse motivo, os cálculos de endereços são realizados de
maneira distinta.
Os cálculos são executados quando um determinado endereço precisa ser acessado, e isso
acontece em tempo de execução. O código assembly é encarregado de executar estes cálculos, pois
durante a compilação é identificada a necessidade de realizá-los e o código assembly
correspondente é gerado.
2.3.2.3 Estruturas de Controle
Comandos como while, do-while, for, if, switch são conhecidos como estruturas de controle.
Como os programas gastam a maior parte do seu tempo executando loops, é importante que o
compilador gere um bom código para eles (SETZER; MELO, 1989; AHO et al., 2008).
O código intermediário gera rótulos para indicar o endereço de salto do comando. Estes
rótulos não podem ser eliminados na etapa de geração de código final, pois os saltos para os pontos
do código ainda são desconhecidos e precisam ser ajustados (LOUDEN, 2004).
O ajuste para os saltos não é um problema a ser resolvido dentro do escopo deste projeto,
uma vez que o código assembly gerado pelo compilador será processado por um montador. Os
rótulos serão passados para o montador que se encarregará de resolver a localização de cada um
deles.
No entanto, o maior problema será a geração de código para esses comandos. Durante a
tradução dos comandos é preciso transformar as características estruturadas em uma representação
equivalente sem estrutura que contenha saltos. Os compiladores utilizam um código padrão que
possibilita a utilização eficiente de um subconjunto de saltos possíveis baseados na máquina-alvo
(LOUDEN, 2004).
A Figura 5 apresenta uma possível declaração para a comando if. A utilização do comando
else é opcional e a estrutura pode ser facilmente alterada para eliminá-lo.
32
Figura 5. Declaração para o comando if
Fonte: Louden (2004).
Nesta declaração existem dois saltos e apenas um deles será executado dependendo do
resultado gerado pelo código de teste, reduzindo o número de instruções de salto. O mesmo pode
ser observado na declaração do comando while na Figura 6.
33
Figura 6. Declaração do comando while
Fonte: Louden (2004).
2.3.2.4 Expressões lógicas
As expressões lógicas ou booleanas são utilizadas em declarações de controle como if e
while e em comandos de atribuição lógica. Para Price e Toscani (2005) dois possíveis métodos de
tradução para essas expressões podem ser utilizados:
• Representação numérica: as constantes true e false são codificadas e avaliadas
numericamente. O resultado dessa avaliação é armazenado em uma variável temporária.
• Representação por fluxo de controle: traduz as expressões lógicas utilizadas nas
instruções de controle e de salto com base no resultado. O resultado da avaliação é
atribuído a um rótulo que indica para qual ponto do programa a execução deve ser
transferida.
No código intermediário as expressões booleanas e aritméticas são computadas da mesma
maneira. Apenas na geração de código objeto que estas expressões são computadas numericamente,
pois a maioria das arquiteturas não possui o tipo booleano (LOUDEN, 2004).
34
Segundo Price e Toscani (2005), a tradução do comando “X = A OR B”, onde A, B e C são
variáveis lógicas, para a notação de três endereços utilizando quádruplas, é mostrada na Figura 7 (a)
e a expressão A< B, onde A e B são variáveis numéricas é mostrada na Figura 7 (b).
T1 = not C T2 = B and T1 T3 = A or T2 X = T3 (a)
100: If A < B goto 103 101: T1 = 0 102: goto 104 103: T1 = 1 104: (b)
Figura 7. Tradução de expressões para notação de três endereços: (a) lógicas; (b) numéricas
Fonte: Price e Toscani (2005).
Na geração de código objeto, os resultados das operações de comparação (>, <, >= e
<=) precisam ser normalizados para zero e um. Algumas arquiteturas exigem que o valor zero ou
um seja carregado, pois o operador de comparação apenas ajusta um código de condição, sendo
necessário gerar saltos adicionais para carregar o valor adequado (LOUDEN, 2004).
Dentro do contexto deste projeto, estas normalizações não serão necessárias. A arquitetura
alvo do compilador proposto possui instruções de comparação que seta ou zera alguns flags do
processador, sinalizando o resultado da operação. Com base nesse resultado, a instrução de desvio
salta para o endereço correspondente. A
Tabela 10 apresenta a descrição das instruções de comparação, saltos e lógicas que o
microcontrolador PicoBlaze executa.
Tabela 10. Instruções de comparação, saltos e lógicas do PicoBlaze
Instrução Descrição COMPARE sx, sy
Compara o conteúdo do registrador sx com o conteúdo do registrador sy. Se sx = sy, o flag ZERO é setado (ZERO = 1). Se sx < sy, o flag CARRY e setado (CARRY = 1).
JUMP Z, aaa Se o flag ZERO estiver setado (ZERO = 1), salta para o endereço aaa. JUMP NZ, aaa Se o flag ZERO estiver zerado (ZERO = 0), salta para o endereço aaa. JUMP C, aaa Se o flag CARRY estiver setado (CARRY = 1), salta para o endereço aaa. JUMP NC, aaa Se o flag CARRY estiver zerado (CARRY = 0), salta para o endereço aaa. TEST sx, sy Operação lógica bit a bit. Se todos os bits da operação lógica forem iguais a
zero, o flag ZERO é setado (ZERO = 1). Se um dos bits da operação lógica for igual a um o, flag CARRY é setado (CARRY = 1).
AND sx, sy Operação lógica bit a bit. OR sx, sy Operação lógica bit a bit. XOR sx, sy Operação lógica bit a bit.
Fonte: Chapman (2008).
35
O montador é responsável pela interpretação destas instruções e pela geração de código de
máquina. Neste projeto apenas a geração de código assembly será realizada e, o único problema a
ser tratado será a geração de código intermediário de boa qualidade.
3 PROJETO
Este capítulo apresenta a análise de requisitos, os diagramas de casos de uso e seus cenários,
os protótipos de tela do sistema e a descrição da gramática que será utilizada para a construção do
compilador.
3.1 Análise de Requisitos
A análise de requisitos foi realiza com o objetivo de identificar o escopo do projeto e definir
as tarefas que sistema irá executar. Na análise, os requisitos funcionais, não funcionais e as regras
de negócio foram verificados.
3.1.1 Requisitos Funcionais
Os requisitos funcionais descrevem o funcionamento do sistema e abrangem as tarefas que
ele irá executar. Na etapa de análise os seguintes requisitos funcionais foram identificados:
• RF01: O sistema permitirá ao usuário escrever aplicações em linguagem de programação
C;
• RF02: O sistema permitirá a depuração passo a passo das aplicações;
• RF03: O sistema permitirá a compilação das aplicações;
• RF04: O sistema deverá gerar código assembly para a arquitetura do microcontrolador
PicoBlaze;
• RF05: O sistema indicará os erros encontrados nas aplicações durante a compilação;
• RF06: Será possível visualizar o estado dos flags do processador através da interface;
• RF07: O sistema permitirá que o usuário habilite e desabilite a interrupção do
processador através da interface;
• RF08: Através da interface, o sistema permitirá que o usuário visualize o
comportamento dos registradores durante a depuração das aplicações;
• RF09: Através da interface, o usuário poderá verificar o comportamento da pilha
CALL/STACK durante a depuração das aplicações;
37
• RF10: O usuário poderá observar o comportamento da memória RAM durante a
depuração das aplicações;
• RF11: O sistema permitirá que o usuário verifique o comportamento de todos os pinos
de entrada e saída durante a depuração das aplicações;
• RF12: O sistema permitirá a inserção de trechos de código assembly nas aplicações;
• RF13: O sistema permitirá a inclusão de bibliotecas descritas em assembly nas
aplicações;
• RF14: O sistema permitirá ao usuário desenvolver bibliotecas em linguagem assembly;
• RF15: O sistema permitirá que o usuário visualize o código assembly gerado; e
• RF16: O sistema possuirá um arquivo de ajuda.
3.1.2 Requisitos Não Funcionais
Os requisitos não funcionais que estão listados abaixo especificam o montador que será
compatível com o arquivo de saída e a linguagem que será utilizada para a implementação do
sistema.
• RNF01: O sistema deverá gerar código assembly para a última versão do módulo
KCPSM; e
• RNF02: O sistema deverá ser desenvolvido em linguagem C++.
3.1.3 Regras de Negócio
As regras de negócio descritas abaixo definem o funcionamento do sistema e seu escopo.
• RN01: Apenas código assembly poderá ser gerado pelo sistema;
• RN02: As aplicações não poderão ser testadas se houver erros em sua descrição;
• RN03: O arquivo de saída será compatível apenas com o montador KCPSM;
• RN04: O sistema utilizará apenas a sintaxe do conjunto de instruções do módulo
KCPSM na etapa de geração de código;
• RN05: O arquivo de ajuda descreverá os comandos suportados juntamente com a sua
sintaxe;
38
• RN06: As constantes numéricas do código fonte deverão ser representáveis em 8 bits; e
• RN07: Apenas bibliotecas em assembly poderão ser incluídas no código fonte.
3.2 Diagramas de Casos de Uso
O diagrama de casos de uso apresentado na Figura 8 define os principais módulos que irão
compor o sistema proposto neste projeto. Os cenários que especificam o fluxo de execução de cada
caso de uso são descritos nas próximas subseções.
Figura 8. Diagrama de casos de uso
3.2.1 UC01 Implementa Aplicação
Este cenário permite que o usuário crie uma nova aplicação e seus passos são listados
abaixo.
O sistema apresenta a interface de desenvolvimento de aplicações; e
O usuário implementa a aplicação em linguagem C.
39
3.2.2 UC02 Implementa Biblioteca
O objetivo deste cenário é possibilitar ao usuário o desenvolvimento de bibliotecas em
linguagem assembly. Os passos que devem ser executados são:
O usuário seleciona um novo arquivo de biblioteca;
O sistema carrega o novo arquivo para edição; e
O usuário implementa em linguagem assembly a nova biblioteca.
3.2.3 UC03 Adiciona Biblioteca
Este cenário disponibiliza ao usuário a inclusão de bibliotecas desenvolvidas em linguagem
assembly no fluxo de projeto das aplicações. Os passos executados neste cenário são:
O usuário seleciona uma biblioteca;
O sistema carrega a biblioteca para o projeto corrente; e
O usuário insere nas aplicações as chamadas das funções da biblioteca.
3.2.4 UC04 Compila Aplicação
O cenário permite ao usuário realizar a compilação de uma aplicação. Os passos realizados
são:
O usuário seleciona a opção de compilação da aplicação; e
O sistema realiza as análises léxica, sintática, semântica e gera o código assembly da
aplicação.
3.2.5 UC05 Testa Aplicação
Este cenário permite que o usuário selecione os componentes do microcontrolador e teste
seu comportamento durante a depuração do código.
O usuário seleciona os componentes do microcontrolador para verificação do seu
comportamento durante a execução da aplicação;
40
O sistema carrega na interface os componentes selecionados pelo usuário;
O usuário seleciona a opção de depuração passo a passo da aplicação; e
O sistema apresenta o comportamento dos componentes selecionados.
3.2.6 UC06 Acessa Ajuda
O acesso ao arquivo de ajuda será feito através dos seguintes passos:
O usuário seleciona a opção de ajuda; e
O sistema apresenta o arquivo de ajuda.
3.3 Definição da Gramática
A definição da gramática foi realizada levando em consideração a arquitetura do
microcontrolador PicoBlaze e seu conjunto de instruções. A especificação da linguagem do
compilador foi baseada em C ANSI, porém algumas definições foram acrescentadas para dar
suporte ao microcontrolador.
A Figura 9 apresenta as definições regulares da linguagem. Esta definição especifica os
caracteres que serão aceitos pela linguagem.
Figura 9. Definições regulares da linguagem
Os tokens são unidades básicas do texto do programa e podem representar uma cadeia de
caracteres, palavras reservadas da linguagem e operadores (PRICE; TOSCANI, 2005). A
Figura 10 mostra os tokens que constituem a gramática do compilador proposto.
41
Figura 10. Definição dos tokens
A gramática é a estrutura utilizada na geração das sentenças ou palavras de uma linguagem.
A especificação da linguagem foi desenvolvida utilizando o GALS e se encontra no apêndice B.
4 DESENVOLVIMENTO
Este capítulo apresenta todas as etapas que foram executadas para a implementação do
compilador C para o PicoBlaze juntamente com as técnicas utilizadas. O desenvolvimento envolveu
a definição da linguagem suportada pelo compilador, definição das ações semânticas para a geração
de código, a implementação do compilador e os algoritmos escolhidos para o seu desenvolvimento.
Ainda neste capítulo encontra-se a descrição da etapa de validação do código assembly gerado pelo
compilador.
4.1 Definição de Aspectos Semânticos
A linguagem suportada pelo compilador foi definida utilizando o GALS (Gerador de
Analisadores Léxicos e Sintáticos). Esta etapa envolveu toda a definição da estrutura do código C
suportado pelo compilador, ou seja, definição das produções de especificação sintática da
linguagem e também a inclusão das ações semânticas.
As ações semânticas são marcações numéricas incluídas dentro das produções de
especificação sintática da linguagem que permitem a leitura dos tokens que são todos os símbolos e
palavras reservadas da linguagem produzidos pelo analisador léxico. Essas ações foram utilizadas
para a geração da analise semântica do compilador, onde foram implementadas as verificações de
tipo, palavras reservadas, declaração de variáveis e a geração do código intermediário.
A Figura 11 apresenta um trecho da especificação sintática da linguagem e as ações que
foram incluídas para a realização da análise sintática e geração de código intermediário.
Figura 11. Especificação sintática da linguagem
43
Neste trecho estão especificadas as estruturas seletivas if, else, switch e os laços de
repetição for, do-while e while.
A estrutura seletiva if executa a verificação de expressões e possui uma lista de comandos
que pode conter qualquer instrução. O mesmo se aplica a estrutura seletiva else, porém sua
execução depende do resultado obtido na verificação da estrutura if. Essas estruturas podem ser
aninhadas de acordo com as necessidades do programador.
As ações semânticas que se encontram nas estruturas if else foram utilizadas para
realizar verificações semânticas e geração de código intermediário da seguinte maneira:
• Ação semântica #62: sinaliza o final de uma expressão. Esta ação é usada para inserir a
instrução condicional no fluxo do código intermediário.
• Ação semântica #67: indica ao analisador sintático que um salto condicional deve ser
incluído no fluxo de instruções do código intermediário. Este salto deverá desviar para o
inicio da lista de comandos da estrutura else, caso ela exista ou para o fim da lista de
comandos da estrutura if.
• Ação semântica #68: indica ao analisador sintático que um rótulo deve ser inserido no
fluxo de instruções do código intermediário. Este rótulo é criado quando a estrutura
else esta aninhada a estrutura if.
• Ação semântica #69: indica o final da estrutura if. Esta ação insere um rótulo no fluxo
de instruções do código intermediário.
A estrutura de seleção múltipla switch testa várias constantes ou variáveis e, quando o
valor coincide, a lista de comandos associada ao case correspondente é executada. As ações
semânticas que se encontram nessa estrutura foram utilizadas pelo analisador semântico da seguinte
maneira:
• Ação #72: Obtêm o operando do switch que será testado com os valores que se
encontram nos comandos case.
• Ação #73: Obtêm o operando do case e insere no fluxo de instruções do código
intermediário da instrução de comparação.
44
• Ação #74: indica que um salto condicional para o próximo case deve ser inserido no
fluxo do código intermediário indicando a inicio da lista de comandos do próximo
case.
• Ação #75: sinaliza o final da lista de comandos de cada case e indica que um salto
incondicional para o fim da estrutura switch deve ser inserido no fluxo de instruções
do código intermediário.
• Ação #76: insere um rótulo no fluxo de instruções do código intermediário que indica o
inicio da lista de comando de cada case.
• Ação #77: insere um rótulo no fluxo de instruções do código intermediário que indica o
fim do estrutura switch.
O laço de repetição for permite um comando de atribuição de um valor a variável que
realiza o controle do laço, uma expressão relacional que sinaliza quando a execução do laço deve
ser interrompida e o incremento que define como a variável de controle do laço vai variar a cada
repetição. As ações semânticas do laço for foram utilizadas da seguinte maneira:
• Ação #17: verifica se a variável de controle foi declarada.
• Ação #18: indica ao analisador semântico que a variável esta sendo inicializada.
• Ação #57: usada para obter o operador de atribuição.
• Ação #61: indica ao analisador semântico que uma instrução de atribuição deve ser
gerada.
• Ação #62: indica ao analisador semântico que a instrução de atribuição deve ser inserida
no fluxo de instruções do código intermediário.
• Ação #78: indica que um rótulo deve ser inserido no fluxo de instruções do código
intermediário sinalizando o inicio do laço for.
• Ação #62: indica que a expressão condicional deve ser inserida no fluxo de instruções do
código intermediário.
• Ação #79: indica que um salto condicional para o final do laço for deve ser inserido no
fluxo de instruções do código intermediário.
45
• Ação #80: indica que a instrução de incremento deve ser gerada e inserida no fluxo de
instruções do código intermediário.
• Ação #81: indica que um salto incondicional para o inicio do laço for deve ser inserido
no fluxo de instruções do código intermediário.
A estrutura de repetição do-while verifica a condição no final do laço que pode ser
qualquer expressão e o laço se repete enquanto ela for verdadeira. As ações semânticas neste laço
de repetição foram utilizadas da seguinte maneira:
• Ação #82: indica que um rótulo deve ser gerado e inserido no fluxo de instruções do
código intermediário para sinalizar o inicio do laço.
• Ação #62: indica ao analisador semântico que a expressão condicional deve ser inserida
no fluxo de instruções do código intermediário.
• Ação #83: indica que um salto condicional para o inicio do laço deve ser gerado e
inserido no fluxo de instruções do código intermediário.
O laço while contém uma condição que pode ser qualquer expressão e enquanto esta
expressão for verdadeira ele se repete. As ações semânticas deste laço são:
• Ação #84: indica que um rótulo deve ser gerado para sinalizar o inicio do laço. Esse
rótulo também deve ser inserido no fluxo de instruções do código intermediário.
• Ação #62: indica ao analisador semântico que a expressão condicional deve ser inserida
no fluxo de instruções do código intermediário.
• Ação #85: indica ao analisador semântico que um salto condicional para o final do laço
deve ser gerado e inserido no fluxo de instruções do código intermediário.
• Ação #86: indica ao analisador semântico que um salto incondicional para o inicio do
laço e um rótulo que sinaliza o fim do laço devem ser gerados e inseridos no fluxo de
instruções do código intermediário.
A especificação sintática de toda a linguagem suportada pelo compilador e o código fonte do
analisador sintático se encontram no apêndice B.
46
4.2 Geração de Código Intermediário
A implementação do analisador semântico do compilador, além de usar as ações semânticas
para armazenar na tabela de símbolos os nomes de rotinas, parâmetros, variáveis e fazer todas as
verificações necessárias em relação aos dados armazenados, também se encarregou de utilizar as
ações semânticas para gerar o código intermediário.
Através das ações semânticas inseridas na definição das produções de especificação sintática
da linguagem foi possível gerar a estrutura que armazena o código intermediário. Nessa estrutura
foram armazenados todos os dados necessários para a geração de código.
O código intermediário foi implementado utilizando triplas, onde três campos foram
definidos: argumento 1, argumento 2 e operação. A tripla foi escolhida, pois sua estrutura é muito
próxima das instruções assembly do PicoBlaze e dispensa a criação de temporários que, no caso do
PicoBlaze são desnecessários, uma vez que todas as operações aritméticas utilizam dois
registradores que armazenam o argumento 1 e o argumento 2 e o resultado da operação sempre é
armazenado no registrador alocado para o argumento 1.
Todos os dados necessários para a criação das triplas são obtidos por meio das ações
semânticas que retornam para o analisador semântico o último token lido antes da ocorrência de
cada ação. Desta maneira argumentos e operações são identificados e armazenados nas triplas.
Após a análise semântica ser executada e o código intermediário ser gerado, a estrutura das
triplas é então usada para gerar código assembly. Nesta etapa os argumentos são trocados por
registradores, os valores das variáveis são lidos e armazenados na memória de dados e as constantes
decimais são passadas para a representação hexadecimal. O gerador de código, que consiste de
rotinas que traduzem as triplas para instruções assembly, é invocado pelo analisador semântico que
envia todos os dados de cada tripla.
Apesar de ser possível gerar código assembly sem possuir um código intermediário, a
decisão de gerar código intermediário foi tornar a geração de código mais simples e permitir que o
mesmo compilador possa ser migrado sem grandes dificuldades para possíveis alterações realizadas
na arquitetura do PicoBlaze, uma vez que se esse microcontrolador é um soft-core, ou seja, um
bloco de hardware escrito em VHDL que pode ser mapeado em diferentes FPGAs, onde novas
funcionalidades podem ser agregadas. A Figura 12 (a) apresenta a estrutura das triplas geradas pelo
compilador para o programa da Figura 12 (b).
47
(a)
#out port 2 int8 x, y ,r, p, i; void main() { x = 9; y = 1; for (i=0; i<5; i++) { y++; } r = x / y; p = x * y + r; output(r, port); output(p, port); } (b)
Figura 12. Triplas: (a) estrutura; (b) programa
Todos os dados necessários para gerar o código intermediário foram inseridos nas triplas. A
partir do campo OP (operação) o analisador semântico identifica qual instrução deve ser gerada,
obtêm os argumentos necessários e invoca o gerador de código que é responsável por traduzir a
tripla para o código assembly.
4.2 Políticas de alocação de memória e registradores
A escolha da política adota para alocar memória e registradores foi a tarefa mais complexa
nesta etapa de implementação, uma vez que o microcontrolador PicoBlaze possui apenas 16
registradores de uso geral e memória de dados com capacidade para armazenar até 64 valores de 8
bits cada.
Levando em consideração o espaço limitado de armazenamento que o microcontrolador
dispõe, as seguintes decisões foram tomadas:
• Os endereços dos pinos de entrada e saída não são armazenados em memória, durante a
geração de código, as constantes definidas são trocadas pelo endereço da porta.
48
• As únicas variáveis que ficam alocadas na memória até o final da execução do programa
são as variáveis globais e as variáveis da rotina principal.
• Quando uma rotina é invocada, seus parâmetros e variáveis são alocados na memória.
• Quanto uma rotina chega ao fim, seus parâmetros e variáveis locais são eliminados da
memória, apenas o valor de retorno é mantido, caso a rotina retorne algum valor.
• Após o resultado de uma instrução aritmética ser armazenado em memória, os
registradores alocados para os argumentos são liberados.
• Após o resultado de uma instrução de deslocamento e rotação ser armazenado em
memória, o registrador alocado para o argumento é liberado.
• Quando uma instrução de entrada é executada, o dado que foi lido na porta de entrada é
armazenado em memória e o registrador é liberado.
• Quando uma instrução de saída é executada, o registrador que armazena o dado enviado
para a porta de saída é liberado.
• Após o resultado de uma instrução lógica ser armazenado na memória, os registradores
alocados para os argumentos são liberados.
Devido ao número restrito de registradores, foi essencial realizar leitura e escrita em
memória para cada instrução. Durante a definição das políticas adotadas não foi levado em
consideração a otimização do código, uma vez que esta etapa não faz parte do escopo do projeto.
4.3 Interface
Esta seção apresenta as telas e os menus que compõem a interface do compilador. Na
Figura 13 é apresentada a tela principal do sistema, onde é possível encontrar o editor de aplicações,
o campo que apresenta as mensagens do compilador, a barra de tarefas e os menus File, Edit, Build
e Debug.
Ainda na tela principal é possível visualizar os campos Registers, Stack CALL/RETURN,
I/O e Memory que são utilizados pelo depurador. Estes campos apresentam o comportamento dos
componentes do PicoBlaze durante a depuração do código assembly.
49
Figura 13. Tela inicial do sistema
A Figura 14 mostra as opções contidas no menu File. Através deste menu é possível criar
uma aplicação C, abrir arquivos com extensão .c e .asm, salvar uma aplicação, imprimir e fechar o
programa.
Figura 14. Menu File
50
A Figura 15 apresenta o menu Edit. Através deste menu é possível refazer ou desfazer uma
ação, copiar, colar, selecionar e procurar palavras na aplicação que se encontra no editor.
Figura 15. Menu Edit
O menu Build permite que o usuário realize a compilação de uma aplicação. A Figura 16
mostra este menu.
Figura 16. Menu Build
51
A Figura 17 mostra o menu Debug onde o programador encontra as opções para depuração passo a passo o arquivo assembly gerado pelo compilador.
Figura 17. Menu Debug
A Figura 18 apresenta a depuração de uma aplicação. Nesta figura é possível observar os
valores armazenados no banco de registradores, na memória de dados, o comportamento da pilha
CALL/RETURN e os valores que estão sendo lidos ou escritos nos pinos do microcontrolador.
52
Figura 18. Depuração código assembly
4.4 Validação do Código Assembly Gerado
Na etapa de validação do código assembly gerado pelo compilador foram utilizados os
montadores pBlazIDE, KCPSM3 e a prototipação física do microcontrolador em FPGA. A Figura
19 apresenta as ferramentas que foram usadas para a validação.
Figura 19. Fluxo de projeto do PicoBlaze
A validação do compilador seguiu o fluxo de projeto do microcontrolador PicoBlaze e
utilizou o conjunto de ferramentas disponíveis para realizar os testes. Inicialmente, o código
53
assembly gerado pelo compilador foi testado no montador pBlazIDE que possibilitou a validação do
comportamento da memória de dados, do banco de registradores e da pilha CALL/RETURN
durante a execução.
Após a validação do código assembly ter sido realizada no montador pBlazIDE, o montador
KCPSM3, que é responsável por gerar a memória de programa do microcontrolador PicoBlaze, foi
utilizado para validar a sintaxe do código assembly. O montador KCPSM3 recebeu como arquivo
de entrada o código assembly gerado pelo compilador e gerou um arquivo de saída contendo a
descrição em VHDL da memória de programa do PicoBlaze. Este arquivo de saída foi integrado
com a descrição em VHDL do PicoBlaze possibilitando a sintetização e gravação do mesmo em
FPGA.
Na etapa de prototipação física, o simulador ISE da Xilinx foi utilizado para sintetizar e
gravar a descrição em VHDL do hardware do microcontrolador PicoBlaze na FPGA. Os arquivos
contendo a descrição em VHDL da memória de programa que foram gerados para a prototipação
encontram-se no apêndice C. Para prototipar o PicoBlaze utilizou-se a placa Spartan-3 da Xilinx
apresentada na Figura 20.
Figura 20. Placa de prototipação Spartan-3
As aplicações disponibilizadas pelo Dalton-Project que foram utilizadas no desenvolvimento
dos testbenchs e na análise do compilador PCCOMP, também foram utilizadas para validar o
compilador desenvolvido. O código assembly gerado pelo compilador para as aplicações do Dalton-
Project se encontra no apêndice A.
54
A Tabela apresenta o número de instruções que foram geradas para cada rotina do Dalton-
Project. Nesta Tabela 11 estão listados os números de instruções geradas manualmente, o número
de instruções que o compilador PCCOMP gerou para cada aplicação e o número de instrução que o
compilador desenvolvido gerou.
Tabela 11. Número de instruções assembly
Rotina Assembly manual Assembly PCCOMP Assembly PBlazeC sqroot.c 73 instruções 183 instruções 77 instruções divmul.c 54 instruções 224 instruções 59 instruções negcnt.c 11 instruções 46 instruções 12 instruções cast.c 25 instruções 151 instruções 61 instruções gcd.c 23 instruções 93 instruções 28 instruções int2bin.c 33 instruções 103 instruções 38 instruções
O número de instruções assembly gerado para cada rotina do Dalton-Project pelo
compilador desenvolvido foi satisfatório e contemplou todos os requisitos estabelecidos na etapa de
projeto deste trabalho. As particularidades de cada rotina estão descritas a seguir:
• A rotina sqroot.c executa instruções de soma, multiplicação e possui um laço de
repetição. Esta rotina executa duas operações de multiplicação que são responsáveis
por gerar o maior número de instruções. Das 77 instruções geradas, 24 delas são
utilizadas para executar apenas duas operações de multiplicação.
• A rotina divmul.c executa operações de soma, multiplicação, divisão e um laço de
repetição. Nesta rotina as operações responsáveis por gerar o maior número de
instruções são a multiplicação e a divisão. Das 59 instruções, 19 delas são geradas
apenas para executar uma multiplicação e uma divisão. As operações de
multiplicação e divisão não são executadas pela unidade lógica aritmética do
PicoBlaze e por este motivo o compilador precisa gerar um bloco de instruções para
realizar estas operações.
• O número de instruções geradas pelo compilador para a rotina negcnt.c ficou bem
próximo do número de instruções geradas manualmente. A rotina negcnt.c executa
operações de soma e possui um laço de repetição.
• A rotina que apresentou a maior diferença em relação ao número de instruções
geradas pelo compilador em comparação ao número de instruções geradas
55
manualmente foi a cast.c. Isto ocorreu, pois esta rotina executa quatro operações de
deslocamento e, para cada operação, é necessário gerar 7 instruções. Como as
instruções de deslocamento do PicoBlaze deslocam apenas um bit ou para a esquerda
ou para a direita, é necessário gerar um laço de repetição e um temporário que realiza
a contagem de repetições que corresponde ao número de bits que deve ser deslocado.
Portanto, das 61 instruções geradas pelo compilador para esta rotina, 28 são
utilizadas para realizar as quatro operações de deslocamento.
As aplicações do Dalton-Project foram compiladas tanto no PCCOMP como no compilador
desenvolvido utilizando dados de oito bits. As rotinas que continham vetores não foram validadas,
pois a implementação de vetores não faz parte do escopo deste projeto. Apesar do conjunto de
aplicações do Dalton-Project ser composto por rotinas simples, foi o suficiente para validar todas as
instruções suportadas pelo microcontrolador PicoBlaze.
4.4 Limitações
O compilador foi desenvolvido tendo como base os padrões da linguagem C, porém algumas
restrições foram estabelecidas durante a definição da linguagem no GALS. A primeira limitação
estabelecida refere-se a estrutura do código fonte C suportada pelo compilador, onde a utilização de
protótipos de rotinas são obrigatórios e o programa principal de ser a primeira rotina da aplicação.
Outra limitação quanto ao código fonte C suportado esta relacionado com o fato do
compilador não suportar arrays unidimensionais e multidimensionais.
5 CONCLUSÕES
O desenvolvimento deste trabalho foi motivado pela parceria estabelecida entre o Mestrado
de Computação Aplicada e a Empresa Intelbras que frequentemente desenvolve produtos utilizando
o microcontrolador PicoBlaze. Além da parceria, a carência de ferramentas de programação em
linguagem de alto nível para microcontrolador PicoBlaze foi outro aspecto que serviu de motivação
para este trabalho.
O principal objetivo do trabalho foi desenvolver uma ferramenta para programação em
linguagem C para o microcontrolador PicoBlaze. Para alcançar esse objetivo, na primeira etapa do
trabalho foi necessário realizar o estudo sobre compiladores, sobre a arquitetura e o conjunto de
instruções do microcontrolador PicoBlaze, conhecer o fluxo de projeto do microcontrolador e
realizar a análise do único compilador C encontrado para o microcontrolador.
Na segunda etapa do trabalho foi realizada a definição dos aspectos semânticos da
linguagem, a geração de código intermediário e as políticas de alocação de memória e registradores.
A decisão de gerar código intermediário foi tomada para tornar o compilador reutilizável, uma vez
que o PicoBlaze é um soft-core e pode ter novas funcionalidades agregadas a ele. O uso do código
intermediário permite que o compilador seja adaptado facilmente as mudanças da arquitetura do
microcontrolador PicoBlaze. Ainda na segunda etapa o código assembly gerado pelo compilador
desenvolvido foi validado por meio de testes utilizando as ferramentas que compõem o fluxo de
projeto do PicoBlaze.
Durante a validação foi possível realizar a comparação entre o desempenho do compilador
desenvolvido e o compilador PCCOMP que foi alvo de análise deste trabalho. O compilador
desenvolvido apresentou melhor desempenho comparado ao PCCOMP em relação ao número de
instruções geradas, que foi menor, em todos os códigos do Dalton Project. Outro aspecto positivo
identificado refere-se a eliminação das restrições identificadas no PCCOMP pelo compilador
desenvolvido.
A principal dificuldade encontrada na etapa de implementação do compilador foi a
utilização do GALS. Durante a definição dos aspectos semânticos do compilador o GALS
apresentou vários conflitos na geração dos analisadores léxico e semântico causando atraso no
desenvolvimento do trabalho.
57
Como sugestão para trabalhos futuros foram identificadas as possibilidades de acrescentar
ao compilador desenvolvido os requisitos de interface que não foram contemplados neste trabalho
como a depuração passo a passo do código C, visualização dos valores dos flags CARRY e ZERO
da unidade lógica aritmética e a possibilidade de habilitar/desabilitar uma interrupção através da
interface. Também é possível acrescentar ao compilador a etapa de otimização de código, suporte a
inclusão de bibliotecas, inclusão de trechos de código assembly no fluxo da aplicação, vetores,
matrizes e dados de 16 e 32 bits.
Espera-se que a ferramenta gerada por este trabalho facilite o desenvolvimento e a validação
de aplicações para o microcontrolador PicoBlaze, oferecendo como vantagens a redução do tempo,
custo e complexidade de um projeto.
REFERÊNCIAS BIBLIOGRÁFICAS
AHO, Alfred V. et al. Compiladores: princípios, técnicas e ferramentas. 2.ed. São Paulo: Pearson Addison-Wesley, 2008.
BECK, Leland L. Desenvolvimento de software básico. 2.ed. Rio de Janeiro: Campus, 1993.
CHAPMAN, Ken. XILINX: PicoBlaze 8-bit Embedded Microcontroller User Guide. 2008. Disponível em: < http://www.xilinx.com/support/documentation/ip_documentation/ug129.pdf>. Acesso em: 18 nov. 2008.
CHAPMAN, Ken. XILINX: PicoBlaze KCPSM3. 2003. Disponível em: <http://www.xilinx.com/ipcenter/processor_central/picoblaze/member/>. Acessado em: 18 nov. 2008.
CRESPO, Rui Gustavo. Processadores de linguagem: da concepção à implementação. Lisboa: IST Press, 1998.
D’AMORE, Roberto. VHDL: descrição e síntese de circuitos digitais. Rio de Janeiro: LTC, 2005.
GESSER, Carlos Eduardo. GALS – Gerador de Analisadores Léxicos e Sintático. Disponível em: < http://gals.sourceforge.net/>. Acessado em: 14 jul. 2009.
HAMBLEN, James O.; FURMAN, Michael D. Rapid prototyping of digital systems. 2.ed. Boston, 2002.
LOUDEN, Kenneth C. Compiladores: princípios e práticas. São Paulo: Pioneira Thomson Learning, 2004.
MOGENSEN, Torben Egidius. Basics of compiler design. Copenhagen: University of Copenhagen, 2008.
MORIMOTO, Carlos E. Hardware: o guia definitivo. Porto Alegre: Sul Editores, 2007.
PODERICO, Francesco. PicoBlaze C Compiler User Manual. Disponível em: <http://rtime.felk.cvut.cz/~krakorj/lib/exe/fetch.php?id=projekty%3Afpga_ml403&cache=cache&media=projekty:pccomp_manual.pdf>. Acessado em: 18 nov. 2008
PRICE, Ana Maria Alencar; TOSCANI, Simão Sirineo. Implementação de linguagens de programação: compiladores. 3.ed. Porto Alegre: Sagra Luzzatto, 2005.
RICARTE, Ivan. Introdução à compilação. Rio de Janeiro: Elsevier, 2008.
SETZER, Valdemar W. A construção de um compilador. 3.ed. Rio de Janeiro: Campus, 1989.
SOUZA, David José de. Desbravando o PIC. 6.ed. São Paulo: Érica, 2003.
THE DALTON PROJECT TEAM. The UCR Dalton Project. University of California – Riverside, 2001. Disponível em: < http://www.cs.ucr.edu/~dalton/>. Acessado em: 14 jul. 2009.
A TESTBENCH
Neste apêndice encontram-se todas as aplicações do Dalton-Project, as aplicações adaptadas
para a implementação dos testbenchs, os testbenchs desenvolvidos manualmente a partir dos
arquivos adaptados e o assembly gerado pelo PCCOMP. O código assembly que foi gerado pelo
compilador desenvolvido a partir das aplicações do Dalton-Project também estão disponibilizados
neste apêndice.
A.1 FIB.C **************** *Dalton-Project* **************** #include <reg51.h> void fib(unsigned char* buf, unsigned char n) { char i; buf[0] = 1; buf[1] = 1; for(i=2; i<n; i++) { buf[i] = buf[i-1] + buf[i-2]; } } void print(unsigned char* buf, unsigned char n) { char i; for(i=0; i<n; i++) { P0 = buf[i]; } } void main() { unsigned char buf[10]; fib(buf, 10); print(buf, 10); while(1); }
********** *Adaptado* ********** int buf[10], i, P0; void fib() { buf[0] = 1; buf[1] = 1; for(i=2; i<10; i++) { buf[i] = buf[i-1] + buf[i-2]; } } void print() { for(i=0; i<10; i++) { P0 = buf[i]; } } void main() { fib(); print(); return 0; }
*********** *Testbench* *********** NAMEREG s0, cont NAMEREG s1, inicial NAMEREG s2, end_1 NAMEREG s3, end_2 NAMEREG s4, op1 NAMEREG s5, op2 ; CONSTANT port, $00 ;main ; LOAD cont, 0 LOAD inicial, $1 LOAD end_1, 0
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _buf_high, 36 CONSTANT _buf_low, 2c CONSTANT _i_high, 2b
61
LOAD end_2, 0 ; CALL metodo_fib CALL metodo_print ; metodo_fib: ; STORE inicial, $00 STORE inicial, $01 LOAD cont, 2 ; loop_for: ; COMPARE cont, 10 JUMP Z, fim_for LOAD end_1, cont LOAD end_2, cont SUB end_1, 1 SUB end_2, 2 FETCH op1, end_1 FETCH op2, end_2 ADD op1, op2 STORE op1, cont ADD cont, 1 JUMP loop_for ; fim_for: RETURN ; metodo_print: ; AND cont, 0 ; loop_mostra ; COMPARE cont, 10 JUMP Z, fim_mostra FETCH op1, cont OUTPUT op1, port ADD cont, 1 JUMP loop_mostra ; fim_mostra:
CONSTANT _i_low, 2a CONSTANT _P0_high, 29 CONSTANT _P0_low, 28 LOAD YL , 28 JUMP _main _fib: LOAD XL, _buf_low SUB YL, 01 STORE XL,(YL) LOAD ZL, 01 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) LOAD ZL, 01 LOAD ZH, 00 SL0 ZL SLA ZH LOAD XL, _buf_low ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 01 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) LOAD ZL, 02 LOAD ZH, 00 STORE ZL, _i_low STORE ZH, _i_high L2: FETCH XL, _i_low FETCH XH, _i_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) LOAD ZL, 0a LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH AND XH, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH XL, _i_low FETCH XH, _i_high ADD XL, 01 ADDCY XH, 00 STORE XL, _i_low STORE XH, _i_high SUB XL, 01 SUBCY XH, 00 JUMP L2 L4: FETCH ZL, _i_low FETCH ZH, _i_high SL0 ZL SLA ZH LOAD XL, _buf_low ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) FETCH ZL, _i_low FETCH ZH, _i_high SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL)
62
LOAD ZL, 01 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH SL0 XL SLA XH LOAD ZL, _buf_low ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) ADD XL, 01 FETCH ZH,(XL) ADD XL, 01 SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _i_low FETCH ZH, _i_high SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) LOAD ZL, 02 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH SL0 XL SLA XH LOAD ZL, _buf_low ADD XL, ZL ADDCY XH, ZH FETCH ZL, (XL) ADD XL, 01 FETCH ZH, (XL) ADD XL, 01 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 ADD XL, ZL ADDCY XH, ZH LOAD ZL, XL FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) JUMP L3 L5: LOAD XL, ZL LOAD XH, ZH RETURN _print: LOAD ZL, 00 LOAD ZH, 00 STORE ZL, _i_low STORE ZH, _i_high L9: FETCH XL, _i_low FETCH XH, _i_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) LOAD ZL, 0a LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH AND XH, 80 JUMP NZ, L14 L13: JUMP L12
63
L14: JUMP L11 L10: FETCH XL, _i_low FETCH XH, _i_high ADD XL, 01 ADDCY XH, 00 STORE XL, _i_low STORE XH, _i_high SUB XL, 01 SUBCY XH, 00 JUMP L9 L11: FETCH ZL, _i_low FETCH ZH, _i_high SL0 ZL SLA ZH LOAD XL, _buf_low ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) ADD XL, 01 FETCH ZH, (XL) ADD XL, 01 STORE ZL, _P0_low STORE ZH, _P0_high JUMP L10 L12: LOAD XL, ZL LOAD XH, ZH RETURN _main: CALL _fib CALL _print LOAD ZL, 00 LOAD ZH, 00 LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ;0 error(s) in compilation
A.2 SQROOT.C **************** *Dalton-Project* **************** #include <reg51.h> #include <math.h> void main() { float x = 3.0; float y = 4.0; float xx, yy, xx_yy, sqrt_xx_yy; xx = x * x; P0 = (unsigned char)xx; yy = y * y; P1 = (unsigned char)yy; xx_yy = xx + yy; P2 = (unsigned char)xx_yy; sqrt_xx_yy = sqrt(xx_yy); P3 = (unsigned char)sqrt_xx_yy; while(1); }
********** *Adaptado* ********** int x, y, xx, yy, xx_yy, num, raiz, P0, P1, P2, P3; void main() { x = 3; y = 4; num = 0; raiz = 0; xx = x*x; P0 = xx; yy = y*y; P1 = yy; xx_yy = xx + yy; P2 = xx_yy; while(num != xx_yy) { raiz++; num = raiz * raiz; } P3 = raiz; }
64
*********** *Testbench* *********** NAMEREG s0, x NAMEREG s1, y ; NAMEREG s2, result_msb NAMEREG s3, result_lsb NAMEREG s4, bit_masc NAMEREG s5, num NAMEREG s6, raiz ; CONSTANT local_x, $00 CONSTANT local_y, $01 CONSTANT local_soma, $02 CONSTANT local_raiz, $03 ; CONSTANT port1, 01 CONSTANT port2, 02 CONSTANT port3, 04 CONSTANT port4, 08 ; ;inicio ; LOAD x, $3 LOAD y, $4 LOAD bit_masc, $01 LOAD result_msb, $00 LOAD result_lsb, $00 LOAD num, 0 LOAD raiz, 0 ; ; multiplica x*x ; mult_loop: TEST x, bit_masc JUMP Z, no_add ADD result_msb, x no_add: SRA result_msb SRA result_lsb SL0 bit_masc JUMP NZ, mult_loop OUTPUT result_lsb, port1 STORE result_lsb, local_x ; ; multiplica y*y ; LOAD bit_masc, $01 LOAD result_msb, $00 LOAD result_lsb, $00 mult_loop1: TEST y, bit_masc JUMP Z, no_add1 ADD result_msb, y no_add1: SRA result_msb SRA result_lsb SL0 bit_masc JUMP NZ, mult_loop1 OUTPUT result_lsb, port2 STORE result_lsb, local_y ; ;soma result de x*x + y*y ; FETCH x, local_x FETCH y, local_y ADD x, y OUTPUT x, port3 STORE x, local_soma ; ;raiz quadrada do resultado da soma ; loop_while: COMPARE num, x JUMP Z, fim_while ADD raiz, 1 ; ;multiplica raiz*raiz
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _x_high, 3f CONSTANT _x_low, 3e CONSTANT _y_high, 3d CONSTANT _y_low, 3c CONSTANT _xx_high, 3b CONSTANT _xx_low, 3a CONSTANT _yy_high, 39 CONSTANT _yy_low, 38 CONSTANT _xx_yy_high, 37 CONSTANT _xx_yy_low, 36 CONSTANT _num_high, 35 CONSTANT _num_low , 34 CONSTANT _raiz_high, 33 CONSTANT _raiz_low, 32 CONSTANT _P0_high , 31 CONSTANT _P0_low , 30 CONSTANT _P1_high , 2f CONSTANT _P1_low , 2e CONSTANT _P2_high , 2d CONSTANT _P2_low , 2c CONSTANT _P3_high , 2b CONSTANT _P3_low , 2a LOAD YL, 2a JUMP _main _main: LOAD ZL, 03 LOAD ZH, 00 STORE ZL, _x_low STORE ZH, _x_high LOAD ZL, 04 LOAD ZH, 00 STORE ZL, _y_low STORE ZH, _y_high LOAD ZL, 00 LOAD ZH, 00 STORE ZL, _num_low STORE ZH, _num_high LOAD ZL, 00 LOAD ZH, 00 STORE ZL, _raiz_low STORE ZH, _raiz_high FETCH XL, _x_low FETCH XH, _x_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _x_low FETCH ZH, _x_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _sign_mult STORE ZL, _xx_low STORE ZH, _xx_high FETCH XL, _xx_low FETCH XH, _xx_high STORE XL, _P0_low STORE XH, _P0_high FETCH XL, _y_low FETCH XH, _y_high
65
; LOAD bit_masc, $01 LOAD result_msb, $00 LOAD result_lsb, $00 mult_loop2: TEST raiz, bit_masc JUMP Z, no_add2 ADD result_msb, raiz no_add2: SRA result_msb SRA result_lsb SL0 bit_masc JUMP NZ, mult_loop2 LOAD num, result_lsb JUMP loop_while fim_while: STORE raiz, local_raiz OUTPUT raiz, port4
SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _y_low FETCH ZH, _y_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _sign_mult STORE ZL, _yy_low STORE ZH, _yy_high FETCH XL, _yy_low FETCH XH, _yy_high STORE XL, _P1_low STORE XH, _P1_high FETCH XL, _xx_low FETCH XH, _xx_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _yy_low FETCH ZH, _yy_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 ADD XL, ZL ADDCY XH, ZH STORE XL, _xx_yy_low STORE XH, _xx_yy_high FETCH XL, _xx_yy_low FETCH XH, _xx_yy_high STORE XL, _P2_low STORE XH, _P2_high L2: FETCH XL, _num_low FETCH XH, _num_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _xx_yy_low FETCH ZH, _xx_yy_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH JUMP NZ, L4 JUMP L3 L4: FETCH XL, _raiz_low FETCH XH, _raiz_high ADD XL, 01 ADDCY XH, 00 STORE XL, _raiz_low STORE XH, _raiz_high SUB XL, 01 SUBCY XH, 00 FETCH XL, _raiz_low FETCH XH, _raiz_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _raiz_low FETCH ZH, _raiz_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _sign_mult STORE ZL, _num_low STORE ZH, _num_high JUMP L2 L3: FETCH XL, _raiz_low FETCH XH, _raiz_high STORE XL, _P3_low STORE XH, _P3_high _end_main: jump _end_main; end of program!
66
; MULT SUBROUTINE _mult: LOAD TMP, 0f LOAD SL, XL LOAD SH, XH LOAD XL, 00 LOAD XH, 00 _m1: SR0 ZH SRA ZL JUMP NC, _m2 ADD XL, SL ADDCY XH, SH _m2: SL0 SL SLA SH SUB TMP, 01 JUMP NZ, _m1 LOAD ZL, XL LOAD ZH, XH RETURN _sign_mult: LOAD TMP2, 00 LOAD TMP, XH AND TMP, 80 JUMP Z, _check_member2 LOAD TMP2, 01 XOR XL, ff XOR XH, ff ADD XL, 01 ADDCY XH, 00 _check_member2: LOAD TMP, ZH AND TMP, 80 JUMP Z, _do_mult XOR TMP2, 01 XOR ZL, ff XOR ZH, ff ADD ZL, 01 ADDCY ZH, 00 _do_mult: CALL _mult AND TMP2, 01 JUMP NZ, _invert_mult RETURN _invert_mult: XOR XL, ff XOR XH, ff ADD XL, 01 ADDCY XH, 00 RETURN ;0 error(s) in compilation
A.2.1 Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT x_end, 00 CONSTANT y_end, 01 CONSTANT xx_end, 02 CONSTANT yy_end, 03 CONSTANT xxyy_end, 04 CONSTANT num_end, 05 CONSTANT raiz_end, 06 main: LOAD S0, 03 STORE S0, x_end LOAD S0, 04 STORE S0, y_end LOAD S0, 00 STORE S0, num_end LOAD S0, 00 STORE S0, raiz_end LOAD S0, 01 LOAD S1, 00 LOAD S2, 00 FETCH S3, x_end mult_loop0: TEST S3, S0 JUMP Z , no_add0 ADD S1, S3 no_add0:
67
SRA S1 SRA S2 SL0 S0 JUMP NZ , mult_loop0 STORE S2, xx_end OUTPUT S2, 00 LOAD S0, 01 LOAD S1, 00 LOAD S2, 00 FETCH S3, y_end mult_loop1: TEST S3, S0 JUMP Z , no_add1 ADD S1, S3 no_add1: SRA S1 SRA S2 SL0 S0 JUMP NZ , mult_loop1 STORE S2, yy_end OUTPUT S2, 01 FETCH S3, xx_end ADD S3, S2 STORE S3, xxyy_end OUTPUT S3, 02 L0: FETCH S0, num_end FETCH S1, xxyy_end COMPARE S0, S1 JUMP C , L1 FETCH S2, raiz_end ADD S2, 01 STORE S2, raiz_end LOAD S13 3, 01 LOAD S14 4, 00 LOAD S15 5, 00 mult_loop2: TEST S2, S3 JUMP Z , no_add2 ADD S4, S2 no_add2: SRA S4 SRA S5 SL0 S3 JUMP NZ , mult_loop2 STORE S5, num_end JUMP L0 L1: OUTPUT S2, 03 JUMP main
A.3 DIVMUL.C **************** *Dalton-Project* **************** #include <reg51.h> void main() { unsigned x = 134; unsigned y = 1; unsigned q, r, p, i; for(i=0; i<12; i++) { y++; } q = x / y; p = q * y + r; P0 = q; P0 = r; P0 = p; while(1); }
********** *Adaptado* ********** int x, y ,r, p, i, p0; void main() { x = 9; y = 1; for (i=0; i<5; i++) { y++; } r = x / y; p = x * y; r = p + r; p0 = r; p0 = p; }
68
*********** *Testbench* *********** CONSTANT port, 01 NAMEREG s0, op1 NAMEREG s1, op2 NAMEREG s3, r NAMEREG s4, p NAMEREG s5, i NAMEREG s6, bit_masc NAMEREG s7, quociente NAMEREG s8, restante NAMEREG s9, result_msb NAMEREG sA, result_lsb ; ;inicio ; LOAD op1, $9 LOAD i, 0 LOAD op2, 1 loop_for: COMPARE i, $5 JUMP NZ, fim_for ADD i, 1 ADD op2, 1 JUMP loop_for fim_for: ; ;DIVISÃO ; LOAD restante, 00 LOAD bit_masc, $80 div_loop: TEST op1, bit_masc SLA restante SL0 quociente COMPARE restante, op2 JUMP C, no_sub SUB restante, op2 ADD quociente, 01 no_sub: SR0 bit_masc JUMP NZ, div_loop LOAD r, quociente OUTPUT r, port STORE r, $00 ; ;MULTIPLICAÇÃO ; LOAD bit_masc, 01 LOAD result_msb, 00 LOAD result_lsb, 00 mult_loop: TEST op2, bit_masc JUMP Z, no_add ADD result_msb, op1 no_add: SRA result_msb SRA result_lsb SL0 bit_masc JUMP NZ, mult_loop LOAD p, result_lsb ADD p, r OUTPUT p, port STORE p, $01
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _x_high, 3f CONSTANT _x_low, 3e CONSTANT _y_high, 3d CONSTANT _y_low, 3c CONSTANT _r_high, 3b CONSTANT _r_low, 3a CONSTANT _p_high, 39 CONSTANT _p_low, 38 CONSTANT _i_high, 37 CONSTANT _i_low, 36 CONSTANT _p0_high,35 CONSTANT _p0_low, 34 CONSTANT _p1_high,33 CONSTANT _p1_low, 32 LOAD YL, 32 JUMP _main _main: LOAD ZL, 09 LOAD ZH, 00 STORE ZL, _x_low STORE ZH, _x_high LOAD ZL, 01 LOAD ZH, 00 STORE ZL, _y_low STORE ZH, _y_high LOAD ZL, 00 LOAD ZH, 00 STORE ZL, _i_low STORE ZH, _i_high L2: FETCH XL, _i_low FETCH XH, _i_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) LOAD ZL, 05 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH AND XH, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH XL, _i_low FETCH XH, _i_high ADD XL, 01 ADDCY XH, 00 STORE XL, _i_low STORE XH, _i_high SUB XL, 01 SUBCY XH, 00 JUMP L2 L4:
69
FETCH XL, _y_low FETCH XH, _y_high ADD XL, 01 ADDCY XH, 00 STORE XL, _y_low STORE XH, _y_high SUB XL, 01 SUBCY XH, 00 JUMP L3 L5: FETCH XL, _x_low FETCH XH, _x_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _y_low FETCH ZH, _y_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _sign_div STORE ZL, _r_low STORE ZH, _r_high FETCH XL, _x_low FETCH XH, _x_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _y_low FETCH ZH, _y_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _sign_mult STORE ZL, _p_low STORE ZH, _p_high FETCH XL, _p_low FETCH XH, _p_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) FETCH ZL, _r_low FETCH ZH, _r_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 ADD XL, ZL ADDCY XH, ZH STORE XL, _r_low STORE XH, _r_high FETCH XL, _r_low FETCH XH, _r_high STORE XL, _p0_low STORE XH, _p0_high FETCH XL, _p_low FETCH XH, _p_high STORE XL, _p1_low STORE XH, _p1_high _end_main: jump _end_main; end of program! ; MULT SUBROUTINE _mult: LOAD TMP, 0f LOAD SL, XL LOAD SH, XH LOAD XL, 00 LOAD XH, 00 _m1: SR0 ZH SRA ZL JUMP NC, _m2 ADD XL, SL ADDCY XH, SH _m2: SL0 SL SLA SH SUB TMP, 01 JUMP NZ, _m1 LOAD ZL, XL LOAD ZH, XH RETURN
70
; DIVISION SUBROUTINE _div: LOAD SL, XL LOAD SH, XH OR SH, SL JUMP NZ, _div_possible RETURN _div_possible: LOAD SH, ZH LOAD SL, ZL LOAD ZH, 00 LOAD ZL, 00 LOAD TMP, 10 _div_start_here: SR0 SH SRA SL SRA ZH SRA ZL SUB XL, ZL SUBCY XH, ZH JUMP NC, _rem_mor_eq_zero ADD XL, ZL ADDCY XH, ZH SL0 KL SLA KH JUMP _sr_div_reg _rem_mor_eq_zero: SL1 KL SLA KH _sr_div_reg: SUB TMP, 01 JUMP Z, _div_done JUMP _div_start_here _div_done: LOAD ZL, KL LOAD ZH, KH RETURN _sign_div: LOAD TMP2, 00 LOAD TMP, XH AND TMP, 80 JUMP Z, _dcheck_member2 LOAD TMP2, 01 XOR XL, ff XOR XH, ff ADD XL, 01 ADDCY XH, 00 _dcheck_member2: LOAD TMP, ZH AND TMP, 80 JUMP Z, _do_div XOR TMP2, 01 XOR ZL, ff XOR ZH, ff ADD ZL, 01 ADDCY ZH, 00 _do_div: CALL _div AND TMP2, 01 JUMP NZ, _invert_div RETURN _invert_div: XOR ZL, ff XOR ZH, ff ADD ZL, 01 ADDCY ZH, 00 RETURN _sign_mult: LOAD TMP2, 00 LOAD TMP, XH AND TMP, 80 JUMP Z, _check_member2 LOAD TMP2, 01 XOR XL, ff XOR XH, ff ADD XL, 01 ADDCY XH, 00 _check_member2: LOAD TMP, ZH AND TMP, 80 JUMP Z, _do_mult XOR TMP2, 01 XOR ZL, ff XOR ZH, ff ADD ZL, 01
71
ADDCY ZH, 00 _do_mult: CALL _mult AND TMP2, 01 JUMP NZ, _invert_mult RETURN _invert_mult: XOR XL, ff XOR XH, ff ADD XL, 01 ADDCY XH, 00 RETURN ;0 error(s) in compilation
A.3.1 Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT x_end, 00 CONSTANT y_end, 01 CONSTANT r_end, 02 CONSTANT p_end, 03 CONSTANT i_end, 04 main: LOAD S0, 09 STORE S0, x_end LOAD S0, 01 STORE S0, y_end LOAD S0, 00 STORE S0, i_end L0: FETCH S0, i_end COMPARE S0, 05 JUMP C , L1 ADD S0, 01 STORE s0, i_end ADD S0, 01 STORE S0, y_end JUMP L0 L1: LOAD S0, 00 LOAD S1, 80 FETCH S3, y_end FETCH S4, x_end div_loop0: TEST S4, S1 SLA S0 SL0 S2 COMPARE S0, S3 JUMP C, no_sub0 SUB S0, S3 ADD S2, 01 no_sub0: SR0 S1 JUMP NZ, div_loop0 STORE S2, r_end LOAD S0, 01 LOAD S1, 00 LOAD S2, 00 FETCH S3, x_end mult_loop0: TEST S3, S0 JUMP Z , no_add0 ADD S1, S3 no_add0: SRA S1 SRA S2 SL0 S0 JUMP NZ , mult_loop0 ADD S3, S2 STORE S3, p_end FETCH S0, r_end FETCH S1, p_end OUTPUT S0, 02 OUTPUT S1, 02 JUMP main
72
A.4 NEGCNT.C **************** *Dalton-Project* **************** #include <reg51.h> void main() { int i; for(i=-960; i<-950; i++) { P0 = (unsigned char)i; } while(1); }
********** *Adaptado* ********** int i, P0; void main() { for(i=-50; i<-40; i++) { P0 = i; } }
*********** *Testbench* *********** NAMEREG s0, reg NAMEREG s1, const CONSTANT port, 01 ; loopwhile: ; LOAD reg, $D8 LOAD const, $CE iniciofor: COMPARE reg, const JUMP Z, fimfor OUTPUT const, port ADD const, 01 JUMP iniciofor fimfor: JUMP loopwhile fim:
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _i, 3f CONSTANT _P0, 3e LOAD YL, 3e JUMP _main _main: LOAD ZL, ce STORE ZL, _i L2: FETCH ZL,_i SUB YL, 01 STORE ZL,(YL) LOAD ZL, d8 FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH ZL, _i ADD ZL, 01 STORE ZL, _i SUB ZL, 01 JUMP L2 L4: FETCH ZL, _i STORE ZL, _P0 JUMP L3 L5: LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ;0 error(s) in compilation
73
A.4.1 Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT i_end, 00 main: LOAD S0, 32 STORE S0, i_end L0: COMPARE S0, 28 JUMP C , L1 ADD S0, 01 OUTPUT S0, 02 JUMP L0 L1: JUMP main
A.5 SORT.C **************** *Dalton-Project* **************** #include <reg51.h> void sort(unsigned char* buf, unsigned char n) { unsigned char i, j, t; for(i=0; i<n; i++) { for(j=i; j<n; j++) { if( buf[i] > buf[j] ) { t = buf[i]; buf[i] = buf[j]; buf[j] = t; } } } P0 = 0; } void print(unsigned char* buf, unsigned char n) { char i; for(i=0; i<n; i++) { P0 = buf[i]; } } void main() { unsigned char buf[] = { 19, 18, 17, 16, 15, 14, 13, 12, 11, 10 }; sort(buf, 10); print(buf, 10); while(1); }
********** *Adaptado* ********** int buf[10]; int i, j, t, P0; void sort() { for(i=0; i<10; i++) { for(j=i; j<10; j++) { if( buf[i] > buf[j] ) { t = buf[i]; buf[i] = buf[j]; buf[j] = t; } } } P0 = 0; } void print() { for(i=0; i<10; i++) { P0 = buf[i]; } } void main() { buf[0] = 19; buf[1] = 18; buf[2] = 17; buf[3] = 16; buf[4] = 15; buf[5] = 14; buf[6] = 13; buf[7] = 12; buf[8] = 11; buf[9] = 10; sort(); print(); }
*********** *Testbench* *********** NAMEREG s0, endereco
******** *PCCOMP* ******** NAMEREG sf , XL
74
NAMEREG s1, op1 NAMEREG s2, op2 NAMEREG s3, op3 NAMEREG s4, op4 NAMEREG s5, op5 NAMEREG s6, op6 NAMEREG s7, op7 NAMEREG s8, op8 NAMEREG s9, op9 NAMEREG sA, op10 NAMEREG sB, cont CONSTANT port, $0 ; main ; AND endereco, 0 ; LOAD op1, 25 LOAD op2, 24 LOAD op3, 23 LOAD op4, 22 LOAD op5, 21 LOAD op6, 20 LOAD op7, 19 LOAD op8, 18 LOAD op9, 17 LOAD op10, 16 ; STORE op1, endereco ADD endereco, 1 STORE op2, endereco ADD endereco, 1 STORE op3, endereco ADD endereco, 1 STORE op4, endereco ADD endereco, 1 STORE op5, endereco ADD endereco, 1 STORE op6, endereco ADD endereco, 1 STORE op7, endereco ADD endereco, 1 STORE op8, endereco ADD endereco, 1 STORE op9, endereco ADD endereco, 1 STORE op10, endereco ; ; libera os registradores ; AND op1, 0 AND op2, 0 AND op3, 0 AND op4, 0 AND op5, 0 AND op6, 0 AND op7, 0 AND op8, 0 AND op9, 0 AND op10, 0 AND cont, 0 AND endereco, 0 ; CALL metodo_sort CALL metodo_print ; metodo_sort: ; LOAD cont, 10 loop_for1: ; COMPARE op1, cont JUMP Z, fim_for1 LOAD op2, op1 ; loop_for2: COMPARE op2, cont JUMP Z, fim_for2 FETCH op3, op1 FETCH op4, op2 loop_if: COMPARE op3, op4 JUMP Z, fim_if JUMP C, loop_for2 STORE op4, op1
NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _buf, 36 CONSTANT _i, 35 CONSTANT _j, 34 CONSTANT _t, 33 CONSTANT _P0, 32 LOAD YL, 32 JUMP _main _sort: LOAD ZL,00 STORE ZL,_i L2: FETCH ZL,_i SUB YL, 01 STORE ZL,(YL) LOAD ZL, 0a FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH ZL, _i ADD ZL, 01 STORE ZL, _i SUB ZL, 01 JUMP L2 L4: FETCH ZL, _i STORE ZL, _j L8: FETCH ZL, _j SUB YL, 01 STORE ZL,(YL) LOAD ZL, 0a FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L13 L12: JUMP L11 L13: JUMP L10 L9: FETCH ZL, _j ADD ZL, 01 STORE ZL, _j SUB ZL, 01 JUMP L8 L10: FETCH ZL, _i L17: LOAD ZH, ZL AND ZH, 80 JUMP Z, L18 LOAD ZH, ff L18: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _j L19: LOAD ZH, ZL
75
STORE op3, op2 fim_if: ADD op2, 1 JUMP loop_for2 fim_for2: ADD op1, 1 JUMP loop_for1 fim_for1: RETURN ; metodo_print: LOAD op1, 0 loop_mostra: COMPARE op1, cont JUMP Z, fim_mostra FETCH op2, op1 OUTPUT op2, port ADD op1, 1 JUMP loop_mostra fim_mostra:
AND ZH, 80 JUMP Z, L20 LOAD ZH, ff L20: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) FETCH XL,(YL) ADD YL, 01 SUB ZL, XL AND ZL, 80 JUMP NZ, L16 JUMP L14 L16: FETCH ZL, _i L21: LOAD ZH, ZL AND ZH, 80 JUMP Z, L22 LOAD ZH, ff L22: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) STORE ZL, _t FETCH ZL, _i L23: LOAD ZH, ZL AND ZH, 80 JUMP Z, L24 LOAD ZH, ff L24: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) FETCH ZL, _j L25: LOAD ZH, ZL AND ZH, 80 JUMP Z, L26 LOAD ZH, ff L26: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) FETCH ZL, _j L27: LOAD ZH, ZL AND ZH, 80 JUMP Z, L28 LOAD ZH, ff L28: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) FETCH ZL, _t FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) L14: JUMP L9 L11: JUMP L3 L5: LOAD ZL, 00 STORE ZL, _P0 LOAD XL, ZL LOAD XH, ZH RETURN _print:
76
LOAD ZL,00 STORE ZL, _i L30: FETCH ZL, _i SUB YL, 01 STORE ZL,(YL) LOAD ZL, 0a FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L35 L34: JUMP L33 L35: JUMP L32 L31: FETCH ZL, _i ADD ZL , 01 STORE ZL, _i SUB ZL, 01 JUMP L30 L32: FETCH ZL, _i L36: LOAD ZH, ZL AND ZH, 80 JUMP Z, L37 LOAD ZH, ff L37: LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) STORE ZL, _P0 JUMP L31 L33: LOAD XL, ZL LOAD XH, ZH RETURN _main: LOAD XL, _buf LOAD ZH, 00 SUB YL, 01 STORE XL,(YL) LOAD ZL, 13 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 01 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 12 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 02 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 11 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 03 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 10 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 04
77
LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0f FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 05 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0e FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 06 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0d FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 07 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0c FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 08 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0b FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 09 LOAD XL, _buf LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) LOAD ZL, 0a FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) CALL _sort CALL _print _end_main: jump _end_main; end of program! ;0 error(s) in compilation
A.6 XRAM.C **************** *Dalton-Project* **************** unsigned char xdata buffer[2048]; void main() { unsigned short i;
********** *Adaptado* ********** int buffer[64], i; void main() { buffer[0] = 1;
78
buffer[0] = 1; for(i=1; i<2048; i++) { buffer[i] = buffer[i - 1] + 1; } while(1); }
for(i=1; i<64; i++) { buffer[i] = buffer[i - 1] + 1; } }
*********** *Testbench* *********** NAMEREG s0, i NAMEREG s1, var NAMEREG s2, endereco ; ;inicio ; LOAD i, $1 STORE i, $0 loop_for: ; COMPARE i, $40 JUMP Z, fim_for LOAD endereco, i SUB endereco, 1 FETCH var, endereco ADD var, 1 STORE var, i ADD i, 1 JUMP loop_for ; fim_for:
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _buffer, 36 CONSTANT _i , 35 LOAD YL, 35 JUMP _main _main: LOAD XL, _buffer SUB YL, 01 STORE XL,(YL) LOAD ZL, 01 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) LOAD ZL, 01 STORE ZL, _i L2: FETCH ZL, _i SUB YL, 01 STORE ZL,(YL) LOAD ZL, 0a FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH ZL, _i ADD ZL, 01 STORE ZL, _i SUB ZL, 01 JUMP L2 L4: FETCH ZL, _i L8: LOAD ZH, ZL AND ZH, 80 JUMP Z, L9 LOAD ZH, ff L9: LOAD XL, _buffer LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH SUB YL, 01 STORE XL,(YL) FETCH ZL, _i L10: LOAD ZH, ZL AND ZH, 80
79
JUMP Z, L11 LOAD ZH, ff L11: SUB YL, 01 STORE ZL,(YL) LOAD ZL, 01 FETCH XL,(YL) ADD YL, 01 SUB XL, ZL LOAD ZL, _buffer LOAD ZH, 00 ADD XL, ZL ADDCY XH, ZH FETCH ZL,(XL) SUB YL, 01 STORE ZL,(YL) LOAD ZL, 01 FETCH XL,(YL) ADD YL, 01 ADD XL, ZL LOAD ZL, XL FETCH ZL,(YL) ADD YL, 01 STORE XL,(ZL) JUMP L3 L5: LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ;0 error(s) in compilation
A.7 CAST.C **************** *Dalton-Project* **************** #include <reg51.h> unsigned char cast(unsigned long l) { return (unsigned char)l; } void main() { unsigned long l = 0x01234567; P0 = cast(l >> 24); P1 = cast(l >> 16); P2 = cast(l >> 8); P3 = cast(l >> 0); while(1); }
********** *Adaptado* ********** int desloc = 8; void cast() { desloc = desloc - 2; } void main() { int l = 255; cast(); P0 = l >> desloc; cast(); P1 = l >> desloc; cast(); P2 = l >> desloc; cast(); P3 = l >> desloc; }
*********** *Testbench* *********** NAMEREG s0, l NAMEREG s1, aux_l NAMEREG s2, desloc NAMEREG s3, aux_desloc NAMEREG s4, endereco CONSTANT port, 01 LOAD desloc, 8 LOAD l, 255 LOAD endereco, 0 loop_principal: CALL cast LOAD aux_desloc, 0 LOAD aux_l, l loop_desloc: COMPARE aux_desloc, desloc JUMP Z, sai_loop_desloc
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _desloc_high, 3f CONSTANT _desloc_low, 3e LOAD YL, 3e JUMP _main
80
SR0 aux_l ADD aux_desloc, 1 JUMP loop_desloc sai_loop_desloc: OUTPUT aux_l, port STORE aux_l, endereco COMPARE aux_l, 255 JUMP Z, fim_principal ADD endereco, 1 JUMP loop_principal fim_principal: ; ; subrotina ; cast: SUB desloc, 2 RETURN
_cast: FETCH XL, _desloc_low FETCH XH, _desloc_high SUB YL, 01 STORE XH,(YL) SUB YL, 01 STORE XL,(YL) LOAD ZL, 02 LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 SUB XL, ZL SUBCY XH, ZH STORE XL, _desloc_low STORE XH, _desloc_high RETURN _main: SUB YL, 0a LOAD XL, YL ADD XL, 08 SUB YL, 01 STORE XL,(YL) LOAD ZL, ff LOAD ZH, 00 FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) LOAD ZL, 08 LOAD ZH, 00 STORE ZL, _desloc_low STORE ZH, _desloc_high CALL _cast LOAD XL, YL ADD XL, 06 SUB YL, 01 STORE XL,(YL) LOAD XL, YL ADD XL, 09 FETCH ZL, (XL) ADD XL, 01 FETCH ZH, (XL) ADD XL, 01 SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _desloc_low FETCH ZH, _desloc_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _asr LOAD ZL, XL LOAD ZH, XH FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) CALL _cast LOAD XL, YL ADD XL, 04 SUB YL, 01 STORE XL,(YL) LOAD XL, YL ADD XL, 09 FETCH ZL,(XL) ADD XL, 01 FETCH ZH,(XL) ADD XL, 01 SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _desloc_low FETCH ZH, _desloc_high FETCH XL,(YL) ADD YL, 01
81
FETCH XH,(YL) ADD YL, 01 call _asr LOAD ZL, XL LOAD ZH, XH FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) CALL _cast LOAD XL, YL ADD XL, 02 SUB YL, 01 STORE XL,(YL) LOAD XL, YL ADD XL, 09 FETCH ZL,(XL) ADD XL, 01 FETCH ZH,(XL) ADD XL, 01 SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _desloc_low FETCH ZH, _desloc_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _asr LOAD ZL, XL LOAD ZH, XH FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) CALL _cast LOAD XL, YL SUB YL, 01 STORE XL,(YL) LOAD XL, YL ADD XL, 09 FETCH ZL,(XL) ADD XL, 01 FETCH ZH, (XL) ADD XL, 01 SUB YL, 01 STORE ZH,(YL) SUB YL, 01 STORE ZL,(YL) FETCH ZL, _desloc_low FETCH ZH, _desloc_high FETCH XL,(YL) ADD YL, 01 FETCH XH,(YL) ADD YL, 01 call _asr LOAD ZL, XL LOAD ZH, XH FETCH XL,(YL) ADD YL, 01 STORE ZL,(XL) ADD XL, 01 STORE ZH,(XL) ADD YL, 0a LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ; ASR SUBROUTINE _asr: OR ZL, ZL RETURN Z SR0 XH SRA XL SUB ZL, 01 JUMP _asr ;0 error(s) in compilation
82
A.7.1 Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT desloc_end, 00 main: CONSTANT l_end, 01 CONSTANT P0_end, 02 CONSTANT P1_end, 03 CONSTANT P2_end, 04 CONSTANT P3_end, 05 LOAD S1, ff STORE S1, l_end LOAD S0, 08 STORE S0, desloc_end CALL cast d0: LOAD S6, 00 COMPARE S0, S6 JUMP Z, f_d0 STORE S7, i_end SR0 S7 ADD S6, 01 JUMP d0 f_d0: STORE S7, P0_end CALL cast d1: LOAD S6, 00 COMPARE S0, S6 JUMP Z, f_d1 STORE S7, i_end SR0 S7 ADD S6, 01 JUMP d1 f_d1: STORE S7, P1_end CALL cast d2: LOAD S6, 00 COMPARE S0, S6 JUMP Z, f_d2 STORE S7, i_end SR0 S7 ADD S6, 01 JUMP d2 f_d2: STORE S7, P2_end CALL cast d3: LOAD S6, 00 COMPARE S0, S6 JUMP Z, f_d3 STORE S7, i_end SR0 S7 ADD S6, 01 JUMP d3 f_d3: STORE S7, P3_end JUMP main cast: SUB S0, 02 STORE S0, desloc_end RETURN
A.8 GCD.C **************** *Dalton-Project* **************** #include <reg51.h> void main() { unsigned char x=47, y=11; while( x != y ) { if( x > y ) {
********** *Adaptado* ********** int x, y; void main() { x=47; y=11; while( x != y ) { if( x > y ) {
83
x -= y; P0 = x; } else { y -= x; P1 = y; } } P2 = x; while(1); }
x -= y; P0 = x; } else { y -= x; P1 = y; } } P2 = x; }
*********** *Testbench* *********** NAMEREG s0, x NAMEREG s1, y NAMEREG s2, end_ram CONSTANT port, 01 CONSTANT port1, 02 CONSTANT port2, 04 LOAD x, $47 LOAD y, $11 loop_while: COMPARE x, y JUMP Z, fim_while if: COMPARE x, y JUMP C, else SUB x, y OUTPUT x, port STORE x, end_ram ADD end_ram, 1 JUMP loop_while else: SUB y, x OUTPUT y, port1 STORE y, end_ram ADD end_ram, 1 JUMP loop_while fim_while: OUTPUT x, port2
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _x , 3f CONSTANT _y , 3e CONSTANT_P2 , 3d LOAD YL, 3d JUMP _main _main: LOAD ZL, 2f STORE ZL, _x LOAD ZL, 0b STORE ZL, _y L2: FETCH ZL, _x L5: LOAD ZH, ZL AND ZH, 80 JUMP Z, L6 LOAD ZH, ff L6: SUB YL, 01 STORE ZL,(YL) FETCH ZL, _y L7: LOAD ZH, ZL AND ZH, 80 JUMP Z, L8 LOAD ZH, ff L8: FETCH XL,(YL) ADD YL, 01 SUB XL, ZL JUMP NZ, L4 JUMP L3 L4: FETCH ZL, _x L12: LOAD ZH, ZL AND ZH, 80 JUMP Z, L13 LOAD ZH, ff L13: SUB YL, 01 STORE ZL,(YL) FETCH ZL, _y L14: LOAD ZH, ZL AND ZH, 80 JUMP Z, L15 LOAD ZH, ff
84
L15: FETCH XL,(YL) ADD YL, 01 SUB ZL, XL AND ZL, 80 JUMP NZ, L11 JUMP L9 L11: FETCH ZL, _x SUB YL, 01 STORE ZL,(YL) FETCH ZL, _y FETCH XL,(YL) ADD YL, 01 SUB XL, ZL STORE XL, _x JUMP L10 L9: FETCH ZL, _y SUB YL, 01 STORE ZL,(YL) FETCH ZL, _x FETCH XL,(YL) ADD YL, 01 SUB XL, ZL STORE XL, _y L10: JUMP L2 L3: FETCH ZL, _x STORE ZL, _P2 LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ;0 error(s) in compilation
A.8.1Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT x_end, 00 CONSTANT y_end, 01 CONSTANT P0_end, 02 CONSTANT P1_end, 03 CONSTANT P2_end, 04 main: LOAD S0, 2f STORE S0, x_end LOAD S1, 0b STORE S1, y_end L0: COMPARE S0, S1 JUMP C , L1 COMPARE S0, S1 JUMP C , L2 SUB S0, S1 STORE S0, x_end STORE S0, P0_end JUMP L3 L2: SUB S0, S1 STORE S0, y_end STORE S0, P1_end L3: JUMP L0 L1: STORE S0, P2_end JUMP main
A.9 INT2BIN.C **************** *Dalton-Project* **************** #include <reg51.h> void main() {
********** *Adaptado* ********** int x, i, desloc, P0; void main() {
85
unsigned char x = 0xaa; unsigned char i; for(i=0; i<8; i++) { P0 = (x & (1<<i)) ? 1 : 0; } while(1); }
x = 170; for(i=0; i<8; i++) { desloc = 1 << i; if (x & desloc) P0 = 1; else P0 = 0; desloc = 0; } }
*********** *Testbench* *********** NAMEREG s0, x NAMEREG s1, i NAMEREG s2, zero NAMEREG s3, um NAMEREG s4, cont NAMEREG s5, reg NAMEREG s6, end_ram CONSTANT port, 01 LOAD i, 0 LOAD x, 170 LOAD zero, 0 LOAD um, 1 loop_for: COMPARE i, 8 JUMP Z, fim_for LOAD cont, 0 LOAD reg, 1 loop_desloca: COMPARE i,cont JUMP Z, fim_desloca ADD cont, 1 SL0 reg JUMP loop_desloca fim_desloca: ADD i, 1 TEST reg, x JUMP Z, out_0 JUMP C, out_1 out_0: OUTPUT zero, port STORE zero, end_ram ADD end_ram, 1 JUMP loop_for out_1: OUTPUT um, port STORE um, end_ram ADD end_ram, 1 JUMP loop_for fim_for:
******** *PCCOMP* ******** NAMEREG sf , XL NAMEREG se , YL NAMEREG sd , ZL NAMEREG sc , XH NAMEREG sa , ZH NAMEREG sb , TMP NAMEREG s9 , SH NAMEREG s8 , SL NAMEREG s7 , KH NAMEREG s6 , KL NAMEREG s5 , TMP2 CONSTANT _x , 3f CONSTANT _i , 3e CONSTANT _desloc, 3d CONSTANT _P0, 3c LOAD YL, 3c JUMP _main _main: LOAD ZL, aa STORE ZL, _x LOAD ZL, 00 STORE ZL, _i L2: FETCH ZL, _i SUB YL, 01 STORE ZL,(YL) LOAD ZL, 08 FETCH XL,(YL) ADD YL, 01 SUB XL, ZL AND XL, 80 JUMP NZ, L7 L6: JUMP L5 L7: JUMP L4 L3: FETCH ZL, _i ADD ZL, 01 STORE ZL, _i SUB ZL, 01 JUMP L2 L4: LOAD ZL, 01 SUB YL, 01 STORE ZL,(YL) FETCH ZL, _i L8: LOAD ZH, ZL AND ZH, 80 JUMP Z, L9 LOAD ZH, ff L9: FETCH XL,(YL) ADD YL, 01 call _lsl
86
LOAD ZL, XL LOAD ZH, XH STORE ZL, _desloc FETCH ZL, _x L13: LOAD ZH, ZL AND ZH, 80 JUMP Z, L14 LOAD ZH, ff L14: SUB YL, 01 STORE ZL,(YL) FETCH ZL, _desloc L15: LOAD ZH, ZL AND ZH, 80 JUMP Z, L16 LOAD ZH, ff L16: FETCH XL,(YL) ADD YL, 01 AND ZL, XL OR ZL, ZL JUMP NZ, L12 JUMP L10 L12: LOAD ZL, 01 STORE ZL, _P0 JUMP L11 L10: LOAD ZL, 00 STORE ZL, _P0 L11: LOAD ZL, 00 STORE ZL, _desloc JUMP L3 L5: LOAD XL, ZL LOAD XH, ZH _end_main: jump _end_main; end of program! ; LSR SUBROUTINE _lsl: OR ZL, ZL RETURN Z SL0 XL SLA XH SUB ZL, 01 JUMP _lsl ;0 error(s) in compilation
A.9.1 Assembly gerado pelo PBlazeC ********* *PBlazeC* ********* CONSTANT x_end, 00 CONSTANT i_end, 01 CONSTANT desloc_end, 02 CONSTANT P0_end, 03 main: LOAD S0, aa STORE S0, x_end LOAD S1, 00 STORE S1, i_end L0: COMPARE S1, 08 JUMP C , L1 ADD S1, 01 d: FECTH S4, 00 COMPARE S1, S4 JUMP Z, f_d ADD S4, 01 SL0 S1 STORE S1, i_end JUMP d
87
f_d: LOAD S2, 01 STORE S2, desloc_end AND S0, S2 JUMP C , L2 LOAD S3, 01 STORE S3, P0_end JUMP L3 L2: LOAD S3, 00 STORE S3, P0_end L3: LOAD S2, 00 STORE S2, desloc_end JUMP L0 L1: JUMP main
B CÓDIGO FONTE
Neste apêndice encontram-se a especificação da linguagem suportada pelo compilador e o
código fonte da análise semântica que foi implementado na etapa de desenvolvimento.
B.1 ESPECIFICAÇÃO SINTÁTICA DA LINGUAGEM <programa> ::= <diretivaPre> <listaPre>; <listaPre> ::= <listaPre> <rotina> | <listaPre> <declaracaoGlobal> | <listaPre> <prototipo> | <rotina> | <declaracaoGlobal> | <prototipo>; /////////////////////////////////INCLUDE, PINOS, GLOBAIS///////////////////////////////// <diretivaPre> ::= <biblioteca> <diretivaPre> | <declaracaopinos> <diretivaPre> | î; ///////////////////////////////PROTÓTIPO DE FUNÇÕES///////////////////////////////////// <tipo> ::= "int8"#1 | "int16"#1 | "int32"#1 | "void"#1; <prototipo> ::= <tipo> id#2 "(" <listaParametro> ")" ";" #12 | <tipo> id#2 "(" ")" ";"#12; <biblioteca> ::= "#include" "<" id#20 "." "asm" ">"; ///////////////////////////////DECLARAÇÃO DE VARIÁVEL LOCAL/////////////////////////////// <listaParametro> ::= <parametro> "," <listaParametro> | <parametro>; <parametro> ::= <tipo> id#3#11 | <tipo> <declaraVetor>#11 | <tipo> <declaraMatriz>#11; <declaracaoLocal> ::= <declaracaovarLocal> ";" ; <declaracaovarLocal> ::= <tipo> <listaidLocal>; <listaidLocal> ::= <listaidLocal> "," id#3#5 | <listaidLocal> "," <declaraVetor>#5 | <listaidLocal> "," <declaraMatriz>#5 | id#3#5 | <declaraVetor>#5 | <declaraMatriz>#5; ///////////////////////////////DECLARAÇÃO DE VARIÁVEL GLOBAL/////////////////////////////// <declaracaoGlobal> ::= <declaracaovarGlobal> ";" ; <declaracaovarGlobal> ::= <tipo> <listaidGlobal>; <listaidGlobal> ::= <listaidGlobal> "," id#3#6 | <listaidGlobal> "," <declaraVetor>#6 | <listaidGlobal> "," <declaraMatriz>#6 | id#3#6 | <declaraVetor>#6 | <declaraMatriz>#6; ////////////////VARIÁVEIS ENVIADAS COMO PARAMETROS EM UMA CHAMADA DE FUNÇÃO/////////////// <listaidfuncao> ::= id#15#17 | id#15#17 "," <listaidfuncao>; /////////////////////////////////////////ROTINAS///////////////////////////////////////// <rotina>::= <tipo> id#2 "("<listaParametro>")"#13 "{" #70<corpo>#71 "}" | <tipo> id#2 "(" ")"#13 "{" #70<corpo>#71 "}"; <corpo> ::= <listacomandos> | <listacomandos> "return" "("id#23#58")" ";"; <chamada_funcao_void> ::= id#14#59 "(" ")"#60 ";" | id#14#59 "(" <listaidfuncao>#16 ")"#60 ";"; <chamada_funcao_retorno> ::= id#14#59 "(" ")" ";" | id#14#59 "(" <listaidfuncao>#16 ")" ";";
89
//////////////////////////////////DECLARAÇÃO PINOS/////////////////////////////////////////// <declaracaopinos> ::= "#in"#1 id#3#6 constInt#22 | "#out"#1 id#3#6 constInt#22 | "#inout"#1 id#3#6 constInt#22 | "#define"#1 id#3#6 constInt#21; //////////////////////////////MATRIZ | VETOR//////////////////////////////////////////////// <declaraVetor> ::= id#4 "["<opInd>#7"]"#9; <declaraMatriz> ::= id#4 "["<opInd>#7"]" "["<opInd>#8"]"#10; <vetor> ::= id#17#24 "["<opd>"]"; <matriz> ::= id#17#24 "["<opd>"]" "["<opd>"]"; <vetorAT> ::= id#17#18 "["<opd>"]"; <matrizAT> ::= id#17#18 "["<opd>"]" "["<opd>"]"; ///////////////////////////////LISTA DE COMANDOS/////////////////////////////////////////// <listacomandos> ::= <comando> <listacomandos> | î; <comando> ::= <declaracaoLocal> | <chamada_funcao_void> | <atribuicao> | <exp> | <entrada> | <saida> | <selecao> | <case> | <repeticao> | <repeticao1> | <repeticao2>; ///////////////////////////////////COMANDOS///////////////////////////////////////////////// <atribuicao> ::= id#17#18 "="#57 <exp>#26#61#62 ";" | id#17#18 "="#57 <chamada_funcao_retorno>#19#60 | id#17#18 "="#57 <vetor>#26#61#62";" | id#17#18 "="#57 <matriz>#26#61#62";" |<vetorAT> "="#57 <exp>#26#61#62 ";" |<vetorAT> "="#57 <chamada_funcao_retorno>#19#60 |<matrizAT> "="#57 <exp>#26#61#62 ";" |<matrizAT> "="#57 <chamada_funcao_retorno>#19#60; <entrada> ::= "input"#65 "(" id#17#24 "," id#17#24 ")" ";"#66; <saida> ::= "output"#65 "(" id#17#24 "," id#17#24 ")" ";"#66; //////////////////////////////////ESTRUTURAS SELETIVAS////////////////////////////////////// <selecao> ::= "if" "(" <exp>#62#67 ")" "{" <listacomandos> "}" <selecao1>#69; <selecao1> ::= "else" "{" #68<listacomandos> "}" | î; ////////////////////////////////ESTRUTURAS SELETIVAS///////////////////////////////////////// <case> ::= "switch" "("<operando>#72")" "{" <listacasos> "}"; <listacasos> ::= <caso> <listacasos> | <caso> ; <caso> ::= "case" <operando>#73 ":" #74<listacomandos>#75 "break"#76 ";" | "default" ":"<listacomandos>#77; ///////////////////////////////LAÇOS DE REPETIÇÃO//////////////////////////////////////////// <repeticao> ::= "for" "(" id#17#18 "="#57 <exp>#61#62 ";" #78<exp>#62#79 ";" <passo>#80 ")" "{" <listacomandos>#81 "}"; <repeticao1> ::= "do" "{" #82<listacomandos> "}" "while" "(" <exp>#62#83 ")" ";"; <repeticao2> ::= "while" "(" #84<exp>#62#85 ")" "{" <listacomandos>#86 "}"; //////////////////////////////////EXPRESSÕES///////////////////////////////////////////////// <exp> ::= <exp> "OR"#55 <exp1>#56 | <exp1>; <exp1> ::= <exp1> "XOR"#53 <exp2>#54 | <exp2>; <exp2> ::= <exp2> "AND"#51 <exp3>#52 | <exp3>;
90
<exp3> ::= <exp3> "<"#49 <exp4>#50 | <exp4>; <exp4> ::= <exp4> ">"#47 <exp5>#48 | <exp5>; <exp5> ::= <exp5> "<="#45 <exp6>#46 | <exp6>; <exp6> ::= <exp6> ">="#43 <exp7>#44 | <exp7>; <exp7> ::= <exp7> "<<"#41 <exp8>#42 | <exp8>; <exp8> ::= <exp8> ">>"#39 <exp9>#40 | <exp9>; <exp9> ::= <exp9> "=="#37 <exp10>#38 | <exp10>; <exp10> ::= <exp10> "!="#35 <exp11>#36 | <exp11>; <exp11> ::= <exp11> "+"#33 <exp12>#34 | <exp12>; <exp12> ::= <exp12> "-"#31 <exp13>#32 | <exp13>; <exp13> ::= <exp13> "/"#29 <exp14>#30 | <exp14>; <exp14> ::= <exp14> "*"#27 <exp15>#28 | <exp15>; <exp15> ::= <operando> | "(" <exp> ")" | <operando> <incDec> ";"#64; <operando> ::= id#17#24 | constInt#21#25 | <matriz> | <vetor>; <opInd> ::= id | constInt; <opd> ::= id#87 | constInt#88; <passo> ::= <operando> <incDec>; <incDec> ::= "++"#63|"--"#63;
B.2 CÓDIGO FONTE SEMANTICO.CS using System; using System.Collections.Generic; using System.Windows.Forms; using System.Collections; using System.IO; namespace PicoBlaze.Compiler { public class Semantico : Constants { private byte var8 = 255; private UInt16 var16 = 65535; private UInt32 var32 = 4294967295; /*....................................................................................*/ private String tk, tipo, tipo_retorno, nome_rotina, nome_var, tipoId, atribuicaoTipo, guarda_var, guarda_op, rotulo_case, var_case, rotulo_for, rotulo_while, rotina_corrente, arg1, arg2, var_hex; private Int16 contaParametros, cont, contInd; private bool flag, var_dimensao; private byte const8, linha, coluna, endereco; private UInt32 const32; private int indtriplas, endLinha, endColuna, indMatriz, contRetorno; /*....................................................................................*/ private Stack<String> Atribuicao = new Stack<String>(); private Stack<String> op = new Stack<String>(); private Stack<String> argumentos = new Stack<String>(); private Stack<String> rotulo = new Stack<String>(); private Stack<String> rotina = new Stack<String>(); private Stack<String> retorno = new Stack<String>(); private Stack<int> indRetorno = new Stack<int>(); private List<Tripla> triplas = new List<Tripla>(); public List<Registros> TabelaSimbolos = new List<Registros>(); private List<Biblioteca> Include = new List<Biblioteca>(); /*....................................................................................*/ Registros aux; Memoria memoria = new Memoria(); GeraRegLabel gera_regLabel = new GeraRegLabel(); GeraCodigo gera_instrucao = new GeraCodigo(); /*.................................................*/ public void executeAction(int action, Token token) /*.................................................*/ { Registros dados = new Registros(); Tripla instrucao = new Tripla();
91
switch (action) { case 1: //tipo de retorno de uma rotina ou tipo da variável this.tk = token.getLexeme(); this.tipo = this.tk; break; //------------------------------------------------- case 2: // nome de uma rotina this.tk = token.getLexeme(); this.nome_rotina = this.tk; this.tipo_retorno = this.tipo; this.rotina_corrente = this.tk; break; //------------------------------------------------- case 3: //obtem o nome de uma variável simples ou de uma constante e armazena na tabela de símbolos this.tk = token.getLexeme(); this.nome_var = this.tk; if (this.tipo == "void") { MessageBox.Show("O tipo: " + this.tipo + " eh invalido na declaracao de variaveis"); } else { for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina && !this.TabelaSimbolos[i].Parametro) { this.flag = true; MessageBox.Show("variavel: " + this.tk + " contem mais de uma declaracao"); break; } if (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].Parametro && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina) { this.flag = true; break; } } if (!this.flag) { dados.LocalizacaoVar = false; dados.Parametro = false; dados.PosicaoParametro = 0; dados.Rotina = false; dados.TipoVar = this.tipo; dados.NomeVar = this.tk; dados.Dimensao = false; dados.Vetor = false; dados.Matriz = false; dados.Linha = 0; dados.Coluna = 0; dados.Declarada = true; dados.Usada = false; dados.Inicializada = false; dados.NomeRotina = this.nome_rotina; dados.Verifica = false; dados.NumParametros = 0; dados.NumVariaveis = 0; dados.EndPino = 0; dados.Valor = "0"; if (this.tipo == "#in" || this.tipo == "#out" || this.tipo == "#inout") { dados.Pino = true; dados.Constante = false; } else { if (this.tipo == "#define") { dados.Constante = true; dados.Pino = false; } }
92
this.TabelaSimbolos.Add(dados); } } break; //------------------------------------------------- case 4: //obtem o nome de uma variável de dimensão (matriz ou vetor) e armazena na tabela de símbolos this.tk = token.getLexeme(); this.nome_var = this.tk; for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina) { this.flag = true; break; } } if (!this.flag) { dados.LocalizacaoVar = false; dados.Parametro = false; dados.PosicaoParametro = 0; dados.Rotina = false; dados.TipoVar = this.tipo; dados.NomeVar = this.tk; dados.Dimensao = true; dados.Vetor = false; dados.Matriz = false; dados.Linha = 0; dados.Coluna = 0; dados.Declarada = false; dados.Usada = false; dados.Inicializada = false; dados.NomeRotina = this.nome_rotina; dados.Verifica = false; dados.NumParametros = 0; dados.NumVariaveis = 0; dados.EndPino = 0; dados.Pino = false; dados.Constante = false; dados.Valor = "0"; this.TabelaSimbolos.Add(dados); } break; //------------------------------------------------- case 5: //sinaliza que a variável declarada é local for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_var) { aux = this.TabelaSimbolos[i]; aux.LocalizacaoVar = false; this.TabelaSimbolos[i] = aux; instrucao.Arg1 = this.nome_var; instrucao.Arg2 = ""; instrucao.Op = "declaraVar"; this.triplas.Add(instrucao); break; } } for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_rotina) { aux = this.TabelaSimbolos[i]; aux.NumVariaveis++; this.TabelaSimbolos[i] = aux; break; } } //aloca memória para as variáveis locais de cada rotina for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.nome_var == this.TabelaSimbolos[i].NomeVar && !this.TabelaSimbolos[i].Parametro) { aux = this.TabelaSimbolos[i]; if (!aux.Dimensao) {
93
aux.EnderecoVar(this.tipo); if (aux.TipoVar == "int8"){ this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); }if (aux.TipoVar == "int16"){ this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); }if (aux.TipoVar == "int32"){ this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(3, this.endereco); } } else{ if (aux.Vetor){ aux.EnderecoVar(aux.TipoVar); this.linha = 0; this.contInd = 0; if (aux.TipoVar == "int8"){ while (this.contInd < aux.Linha){ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.contInd++; } } else{ if (aux.TipoVar == "int16"){ while (this.contInd < aux.Linha){ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.contInd++; } } else{ while (this.contInd < aux.Linha){ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(3, this.endereco); this.contInd++; } } } } else{ if (aux.Matriz){ aux.EnderecoMatriz(aux.TipoVar, aux.Linha); this.linha = 0; this.coluna = 0; this.endLinha = aux.Linha; this.endColuna = aux.Coluna; this.contInd = 0; this.indMatriz = 0; if (aux.TipoVar == "int8"){ while (this.endLinha > 0){ while (this.contInd < this.endColuna){ this.endereco = memoria.AlocaRam(aux.NomeVar);
94
if (this.contInd == 0){ aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } } else{ if (aux.TipoVar == "int16"){ this.endColuna = this.endColuna * 2; while (this.endLinha > 0){ while (this.contInd < this.endColuna){ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0){ aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } } else{ this.endColuna = this.endColuna * 4; while (this.endLinha > 0){ while (this.contInd < this.endColuna){ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0){ aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } } } } } } this.TabelaSimbolos[i] = aux; } } break; //------------------------------------------------- case 6: //sinaliza que a variável declarada é global for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_var) { aux = this.TabelaSimbolos[i]; aux.LocalizacaoVar = true; //variável global aux = this.TabelaSimbolos[i]; if (!aux.Dimensao)//variável simples { if (this.aux.TipoVar == "#define" || this.aux.TipoVar == "int8") { aux.EnderecoVar("int8"); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; if (this.TabelaSimbolos[i].TipoVar == "#define") instrucao.Op = "declaraConst"; else
95
{ if (aux.TipoVar != "int8") instrucao.Op = "declaraPino"; else instrucao.Op = "declaraVar"; } this.triplas.Add(instrucao); } if (aux.TipoVar == "int16") { aux.EnderecoVar("int16"); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraVar"; this.triplas.Add(instrucao); } if (aux.TipoVar == "int32") { aux.EnderecoVar("int32"); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(3, this.endereco); instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraVar"; this.triplas.Add(instrucao); } } else { if (aux.Vetor) { aux.EnderecoVar(aux.TipoVar); this.linha = 0; this.contInd = 0; if (aux.TipoVar == "int8") { while (this.contInd < aux.Linha) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.contInd++; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraVetor"; this.triplas.Add(instrucao); } else { if (aux.TipoVar == "int16") { while (this.contInd < aux.Linha) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.contInd++; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraVetor"; this.triplas.Add(instrucao); } else { while (this.contInd < aux.Linha)
96
{ this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(3, this.endereco); this.contInd++; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraVetor"; this.triplas.Add(instrucao); } } } else { if (aux.Matriz) { aux.EnderecoMatriz(aux.TipoVar, aux.Linha); this.linha = 0; this.coluna = 0; this.endLinha = aux.Linha; this.endColuna = aux.Coluna; this.contInd = 0; this.indMatriz = 0; if (aux.TipoVar == "int8") { while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraMatriz"; this.triplas.Add(instrucao); } else { if (aux.TipoVar == "int16") { this.endColuna = this.endColuna * 2; while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraMatriz";
97
this.triplas.Add(instrucao); } else { this.endColuna = this.endColuna * 4; while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } instrucao.Arg1 = aux.NomeVar; instrucao.Arg2 = ""; instrucao.Op = "declaraMatriz"; this.triplas.Add(instrucao); } } } } } this.TabelaSimbolos[i] = aux; } } break; //------------------------------------------------- case 7: //obtem o índice linha this.tk = token.getLexeme(); this.linha = byte.Parse(this.tk); break; //------------------------------------------------- case 8: //obtem o índice coluna this.tk = token.getLexeme(); this.coluna = byte.Parse(this.tk); break; //------------------------------------------------- case 9: //marca a variável como vetor e armazena o índice linha for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina) { if (this.TabelaSimbolos[i].Dimensao && !this.TabelaSimbolos[i].Declarada) { aux = this.TabelaSimbolos[i]; aux.Declarada = true; aux.Vetor = true; aux.Linha = this.linha; this.TabelaSimbolos[i] = aux; break; } } } break; //------------------------------------------------- case 10: //marca a variável como matriz e armazena o índice linha e coluna for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].Vetor == false && this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina) { if (this.TabelaSimbolos[i].Dimensao && !this.TabelaSimbolos[i].Declarada) { aux = this.TabelaSimbolos[i]; aux.Declarada = true; aux.Matriz = true; aux.Linha = this.linha;
98
aux.Coluna = this.coluna; this.TabelaSimbolos[i] = aux; break; } } } break; //------------------------------------------------- case 11: //marca a variável como parametro de rotina (declaração prototipo), se já marcada, apenas confere (declaração rotina) for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina && !this.TabelaSimbolos[i].Parametro { aux = this.TabelaSimbolos[i]; aux.Parametro = true; aux.PosicaoParametro = this.contaParametros; this.TabelaSimbolos[i] = aux; this.contaParametros++; break; } else { if (this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina && this.TabelaSimbolos[i].Parametro) { if (this.TabelaSimbolos[i].TipoVar != this.tipo) MessageBox.Show("Parametro '" + this.nome_var + "' com tipo incompativel"); if (!this.TabelaSimbolos[i].Dimensao && (this.linha != 0 || this.coluna != 0)) MessageBox.Show("Erro na declaracao do parametro '" + this.nome_var + "'. Numero de elementos inexistente"); if (this.TabelaSimbolos[i].Dimensao) { if (this.TabelaSimbolos[i].Vetor) { if (this.TabelaSimbolos[i].Linha != this.linha) MessageBox.Show("Erro na declaracao do parametro '" + this.nome_var + "'. Indice incorreto"); } else { if (this.TabelaSimbolos[i].Matriz) { if (this.TabelaSimbolos[i].Linha != this.linha || this.TabelaSimbolos[i].Coluna != this.coluna) MessageBox.Show("Erro na declaracao do parametro '" + this.nome_var + "'. Indice incorreto"); } } } aux = this.TabelaSimbolos[i]; aux.Verifica = true; this.TabelaSimbolos[i] = aux; this.linha = 0; this.coluna = 0; break; } } } break; //------------------------------------------------- case 12: //se for a declaração de um protótipo, armazena dados.LocalizacaoVar = false; dados.Parametro = false; dados.PosicaoParametro = 0; dados.Rotina = true; dados.TipoVar = this.tipo_retorno; dados.NomeVar = this.nome_rotina; dados.Dimensao = false; dados.Vetor = false; dados.Matriz = false; dados.Linha = 0; dados.Coluna = 0; dados.Declarada = true; dados.Usada = false;
99
dados.Inicializada = false; dados.NomeRotina = ""; dados.Verifica = false; dados.EndPino = 0; dados.Constante = false; dados.Pino = false; dados.Valor = "0"; dados.NumParametros = this.contaParametros; this.TabelaSimbolos.Add(dados); this.contaParametros = 0; break; //------------------------------------------------- case 13: // se for declaração do main armazena senão confere if (this.nome_rotina == "main") //declaração main { dados.LocalizacaoVar = false; dados.Parametro = false; dados.PosicaoParametro = 0; dados.Rotina = true; dados.TipoVar = this.tipo_retorno; dados.NomeVar = this.nome_rotina; dados.Dimensao = false; dados.Vetor = false; dados.Matriz = false; dados.Linha = 0; dados.Coluna = 0; dados.Declarada = true; dados.Usada = false; dados.Inicializada = false; dados.NomeRotina = ""; dados.Verifica = false; dados.NumParametros = 0; this.TabelaSimbolos.Add(dados); this.flag = true; this.rotina.Push(this.nome_rotina); } else { this.rotina.Push(this.nome_rotina); foreach (Registros ind in this.TabelaSimbolos) { if (ind.NomeVar != "main") { if (ind.NomeVar == this.nome_rotina && ind.TipoVar == this.tipo_retorno) { this.flag = true; break; } } } } if (!this.flag) MessageBox.Show("A rotina: " + this.nome_rotina + " foi declarada incorretamente"); this.tipo_retorno = ""; break; //------------------------------------------------- case 14: //obtem o nome de uma rotina em uma chamada de função this.tk = token.getLexeme(); for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].Rotina && this.TabelaSimbolos[i].NomeVar == this.tk) { if (this.tk != "main") { this.nome_rotina = this.tk; this.tipo_retorno = this.TabelaSimbolos[i].TipoVar; this.cont = 0; break; } else { MessageBox.Show("Chamada de funcao incorreta: " + this.tk); break; } } } break; //------------------------------------------------- case 15: //conta os paramatros que estão sendo enviados em uma chamada de função e
100
verifica se o tipo é compatível this.tk = token.getLexeme(); if (this.nome_rotina != "main") { for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].NomeRotina == this.rotina_corrente) { this.tipo = this.TabelaSimbolos[i].TipoVar if (this.TabelaSimbolos[i].Dimensao) { this.var_dimensao = this.TabelaSimbolos[i].Dimensao; if (this.TabelaSimbolos[i].Vetor) this.linha = this.TabelaSimbolos[i].Linha; else { if (this.TabelaSimbolos[i].Matriz) { this.linha = this.TabelaSimbolos[i].Linha; this.coluna = this.TabelaSimbolos[i].Coluna; } } } break; } } for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeRotina == this.nome_rotina && this.TabelaSimbolos[i].PosicaoParametro == this.cont) { if (this.TabelaSimbolos[i].TipoVar != this.tipo MessageBox.Show("O parametro: '" + this.tk + "' da rotina: '" + this.nome_rotina + "' possui tipo incompativel"); if (this.TabelaSimbolos[i].Dimensao != this.var_dimensao) MessageBox.Show("O parametro '" + this.tk + "' da rotina '" + this.nome_rotina + "' eh invalido"); if (this.TabelaSimbolos[i].Vetor) { if (this.TabelaSimbolos[i].Linha != this.linha) MessageBox.Show("O indice do parametro'" + this.tk + "' da rotina '" + this.nome_rotina + "' eh invalido"); } else { if (this.TabelaSimbolos[i].Linha != this.linha || this.TabelaSimbolos[i].Coluna != this.coluna) MessageBox.Show("O indice do parametro'" + this.tk + "' da rotina '" + this.nome_rotina + "' eh invalido"); } this.linha = 0; this.coluna = 0; this.var_dimensao = false; break; } } this.cont++; } break; //------------------------------------------------- case 16: //verifica se o número de parametros enviados em uma chamada de função são válidos for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_rotina) { aux = this.TabelaSimbolos[i]; if (aux.NumParametros > this.cont) MessageBox.Show("Falta parametros, rotina: " + this.nome_rotina); if (aux.NumParametros < this.cont) MessageBox.Show("Parametros as mais na rotina: " + this.nome_rotina); break; } } break; //------------------------------------------------- case 17: //verifica se a variável foi declarada this.tk = token.getLexeme();
101
for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk) { aux = this.TabelaSimbolos[i]; aux.Usada = true; this.TabelaSimbolos[i] = aux; this.flag = true; break; } } if (!this.flag) MessageBox.Show("A variavel: '" + this.tk + "' nao foi declarada"); break; //------------------------------------------------- case 18: // sinaliza que a variável foi inicializada (atribuição) this.tk = token.getLexeme(); for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if ((this.tk == this.TabelaSimbolos[i].NomeVar && this.TabelaSimbolos[i].NomeRotina == this.rotina_corrente && !this.TabelaSimbolos[i].LocalizacaoVar) || (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].LocalizacaoVar && !this.TabelaSimbolos[i].Constante)) { aux = this.TabelaSimbolos[i]; aux.Inicializada = true; this.atribuicaoTipo = aux.TipoVar; this.TabelaSimbolos[i] = aux; this.guarda_var = tk; this.argumentos.Push(this.tk); this.flag = true; break; } } if (!this.flag) MessageBox.Show("O valor da constante '" + this.tk + "' nao pode ser alterado"); break; //------------------------------------------------- case 19: //verifica se o tipo da variável que receberá o retorno de uma rotina é válido for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.guarda_var) { if (this.TabelaSimbolos[i].TipoVar != this.tipo_retorno) { MessageBox.Show("A variavel: '" + this.guarda_var + "' possui tipo incompativel com o do retorno da funcao"); break; } this.retorno.Push(this.guarda_var); break; } } break; //------------------------------------------------- case 20: //armazena o nome do arquivo incluído (biblioteca) this.tk = token.getLexeme(); Biblioteca arquivo = new Biblioteca(); arquivo.NomeArquivo = this.tk; this.Include.Add(arquivo); break; //------------------------------------------------- case 21: // verifica se a constante esta dentro das faixas de valores (8, 16, 32 bits)e armazena seu valor this.tk = token.getLexeme(); this.const32 = UInt32.Parse(tk); if (this.const32 > this.var32 || this.const32 < 0) MessageBox.Show("A constante: '" + this.tk + "' eh invalida"); else { if (this.tipo == "#define") { for (int i = 0; i < this.TabelaSimbolos.Count; i++)
102
{ if (this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].Constante) { aux = this.TabelaSimbolos[i]; aux.Valor = this.tk; aux.Inicializada = true; this.TabelaSimbolos[i] = aux; } } } } break; //------------------------------------------------- case 22: //verifica se os endereços atribuidos nas declarações de E/S são válidos e aramazena o endereço do pino this.tk = token.getLexeme(); if (this.tipo == "#in" || this.tipo == "#out" || this.tipo == "#inout") { this.const8 = byte.Parse(tk); if (this.const8 > this.var8 || this.const8 < 0) MessageBox.Show("O endereco: '" + this.tk + "' atribuido ao pino eh invalido"); else { for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.nome_var && this.TabelaSimbolos[i].Pino) { aux = this.TabelaSimbolos[i]; aux.EndPino = this.const8; aux.Inicializada = true; this.TabelaSimbolos[i] = aux; } } } } break; //------------------------------------------------- case 23: // verifica se a variável que esta sendo retornada tem tipo compatível com o tipo de retorno da rotina this.tk = token.getLexeme(); for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk) { this.tipo = this.TabelaSimbolos[i].TipoVar; this.nome_rotina = this.TabelaSimbolos[i].NomeRotina; break; } } for (int j = 0; j < this.TabelaSimbolos.Count; j++) { if (this.TabelaSimbolos[j].NomeVar == this.nome_rotina) { this.tipo_retorno = this.TabelaSimbolos[j].TipoVar; break; } } if (this.tipo != this.tipo_retorno) MessageBox.Show("A variavel que esta sendo retornada da rotina '" + this.nome_rotina + "' possui tipo incompativel"); break; //------------------------------------------------- case 24: //obtem o tipo da variável usada em uma expressão this.tk = token.getLexeme(); if(!this.flag) this.argumentos.Push(this.tk); //variável for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.tk && this.TabelaSimbolos[i].NomeRotina == this.nome_rotina) { this.Atribuicao.Push(this.TabelaSimbolos[i].TipoVar); break; } } break;
103
//------------------------------------------------- case 25:// obtem o tipo da constante usada em uma expressão this.tk = token.getLexeme(); this.const32 = UInt32.Parse(tk); if(this.const32 <= 15) this.var_hex = "0" + Convert.ToString(this.const32, 16); else this.var_hex = Convert.ToString(this.const32, 16); this.argumentos.Push(this.var_hex); if (this.const32 <= this.var8) this.Atribuicao.Push("int8"); if (this.const32 > this.var8 && this.const32 <= this.var16) this.Atribuicao.Push("int16"); if (this.const32 > this.var16 && this.const32 <= this.var32) this.Atribuicao.Push("int32"); this.var_hex = ""; break; //------------------------------------------------- case 26: /*Verifica se os tipos das variáveis de uma expressão são compátiveis com o tipo da variável que receberá o resultado*/ if (this.atribuicaoTipo != "int32") { while (this.Atribuicao.Count > 0) { this.tipoId = this.Atribuicao.Pop(); if (this.atribuicaoTipo == "int8") { if (this.tipoId != "int8") MessageBox.Show("Nao e permitido atribuir '" + this.tipoId + "' para 'int8'"); } if (this.atribuicaoTipo == "int16") { if (this.flag && this.tipoId == "int32") MessageBox.Show("Nao e permitido atribuir '" + this.tipoId + "' para 'int16'"); else { if (this.tipoId == "int32") MessageBox.Show("Nao e permitido atribuir '" + this.tipoId + "' para 'int16'"); } } } } this.Atribuicao.Clear(); break; //------------------------------------------------- case 27: //obtem o operador '*' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 28: //sinaliza o final de uma multiplicação instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 29: //obtem o operador '/' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 30: //sinaliza o final de uma divisão instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break;
104
//------------------------------------------------- case 31: //obtem o operador '-' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 32: //sinaliza o final de uma subtração instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 33://obtem o operador '+' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 34: //sinaliza o final de uma soma instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 35: //obtem o operador relacional '!=' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 36: // sinaliza o final da operação '!=' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 37://obtem o operador '==' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 38://sinaliza o final da operação de comparação '==' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 39://obtem o operador '>>' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 40: //sinaliza o fim da operação de deslocamento '>>' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 41://obtem o operador '<<' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 42://sinaliza o final da operação de deslocamento '<<' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop();
105
instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 43://obtem o operando '>=' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 44:// sinaliza o final da operação de comparação '>=' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 45: //obtem o operador '<=' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 46://sinaliza o final de uma operação de comparação '<=' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 47://obtem o operador '>' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 48://sinaliza o final da operação de comparação '>' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 49://obtem o operador '<' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 50://sinaliza o final da operação de comparação '<' instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.Atribuicao.Clear(); break; //------------------------------------------------- case 51://obtem o operador AND this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 52://sinaliza o final da operação AND instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 53://obtem o operador XOR this.tk = token.getLexeme(); this.op.Push(this.tk); break;
106
//------------------------------------------------- case 54:// sinaliza o final da operação XOR instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 55://obtem o operador OR this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 56://sinaliza o final da operação OR instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.argumentos.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 57:// obtem o operador de atribuição this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 58: //gera retorno this.tk = token.getLexeme(); this.contRetorno = this.indRetorno.Count; for (int i = 0; i < this.contRetorno; i++) { this.triplas[this.indRetorno.Pop()].Arg2 = this.tk; } this.contRetorno = 0; break; //------------------------------------------------- case 59:// empilha o nome da rotina this.tk = token.getLexeme(); this.rotina.Push(this.tk); break; //------------------------------------------------- case 60: //cria chamada de função instrucao.Op = "chamada"; instrucao.Arg1 = this.rotina.Pop(); instrucao.Arg2 = ""; this.triplas.Add(instrucao); for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == instrucao.Arg1 && this.TabelaSimbolos[i].TipoVar != "void") { Tripla inst1 = new Tripla(); inst1.Arg1 = this.argumentos.Pop(); inst1.Arg2 = ""; inst1.Op = "="; this.triplas.Add(inst1); this.indRetorno.Push((this.triplas.Count) - 1); break; } } break; //------------------------------------------------- case 61://inicialização, atribuição instrucao.Arg2 = this.argumentos.Pop(); instrucao.Arg1 = this.argumentos.Pop(); instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); break; //------------------------------------------------- case 62://sinaliza o fim de uma expressão this.indtriplas = this.triplas.Count;
107
if (this.triplas[this.indtriplas - 1].Op != "==" && this.triplas[this.indtriplas - 1].Op != "!=" && this.triplas[this.indtriplas - 1].Op != ">" && this.triplas[this.indtriplas - 1].Op != "<" && this.triplas[this.indtriplas - 1].Op != ">=" && this.triplas[this.indtriplas - 1].Op != "<=") { for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.guarda_var && this.TabelaSimbolos[i].NomeRotina == this.rotina_corrente) { this.triplas[this.indtriplas - 1].Rotina = this.rotina_corrente; this.argumentos.Clear(); this.op.Clear(); break; } } } break; //------------------------------------------------- case 63://obtem o operador de incremento ou decremento '++', '--' this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 64://sinaliza o final de uma instrução de incremento/decremento, fora do laço FOR instrucao.Arg1 = this.argumentos.Pop(); instrucao.Arg2 = "01"; instrucao.Op = this.op.Pop(); this.triplas.Add(instrucao); this.argumentos.Clear(); this.op.Clear(); this.guarda_var = ""; this.guarda_op = ""; break; //------------------------------------------------- case 65: //obtem operação de entrada ou saída (input / output) this.tk = token.getLexeme(); this.op.Push(this.tk); break; //------------------------------------------------- case 66://sinaliza o final de uma operação entrada ou de saída this.guarda_op = this.op.Pop(); this.guarda_var = this.argumentos.Pop(); for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.TabelaSimbolos[i].NomeVar == this.guarda_var && this.TabelaSimbolos[i].Pino) { if ((this.TabelaSimbolos[i].TipoVar == "#in" && this.guarda_op == "input") || (this.TabelaSimbolos[i].TipoVar == "#out" && this.guarda_op == "output") || (this.TabelaSimbolos[i].TipoVar == "#inout" && this.guarda_op == "input" ) || (this.TabelaSimbolos[i].TipoVar == "#inout" && this.guarda_op == "output")) { instrucao.Arg1 = this.argumentos.Pop(); instrucao.Arg2 += this.TabelaSimbolos[i].NomeVar; instrucao.Op = this.guarda_op; this.triplas.Add(instrucao); flag = true; break; } } } if (!flag) MessageBox.Show("Endereco de pino invalido"); break; //------------------------------------------------- case 67://desvio condicional if. Cria label para a o else, caso ele exista, ou para o fim do if
108
instrucao.Op = "loopC"; //loop condicional instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; this.triplas.Add(instrucao); this.rotulo.Push(instrucao.Arg1); break; //------------------------------------------------- case 68:// desvio else. Cria label, desempilha o atual e empilha o label criado instrucao.Op = "loopI"; //loop incondicional instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; this.triplas.Add(instrucao); Tripla instrucao1 = new Tripla(); instrucao1.Arg1 = this.rotulo.Pop(); instrucao1.Arg2 = ""; instrucao1.Op = "label"; this.triplas.Add(instrucao1); this.rotulo.Push(instrucao.Arg1); break; //------------------------------------------------- case 69://desempilha o label, fim if/else instrucao.Op = ""; instrucao.Arg1 = this.rotulo.Pop(); instrucao.Arg2 = ""; instrucao.Op = "label"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 70:// inicio da uma rotina cria rotulo instrucao.Arg1 = this.nome_rotina; instrucao.Arg2 = ""; instrucao.Op = "label"; this.triplas.Add(instrucao); Tripla inst2 = new Tripla(); if (this.nome_rotina != "main") { for (int i = 0; i < this.TabelaSimbolos.Count; i++) { if (this.nome_rotina == this.TabelaSimbolos[i].NomeRotina && this.TabelaSimbolos[i].Parametro) { aux = this.TabelaSimbolos[i]; if (!aux.Dimensao) { aux.EnderecoVar(aux.TipoVar); if (aux.TipoVar == "int8") { this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); inst2.Arg1 = this.aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } if (aux.TipoVar == "int16") { this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); inst2.Arg1 = this.aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } if (aux.TipoVar == "int32") { this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar);
109
aux.setEndereco(3, this.endereco); inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } } else { if (aux.Vetor) { aux.EnderecoVar(aux.TipoVar); this.linha = 0; this.contInd = 0; if (aux.TipoVar == "int8") { while (this.contInd < aux.Linha) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.contInd++; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } else { if (aux.TipoVar == "int16") { while (this.contInd < aux.Linha) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.contInd++; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } else { while (this.contInd < aux.Linha) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(0, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(1, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(2, this.endereco); this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) aux.setEndereco(3, this.endereco); this.contInd++; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } } } else { if (aux.Matriz) { aux.EnderecoMatriz(aux.TipoVar, aux.Linha); this.linha = 0; this.coluna = 0; this.endLinha = aux.Linha;
110
this.endColuna = aux.Coluna; this.contInd = 0; this.indMatriz = 0; if (aux.TipoVar == "int8") { while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } else { if (aux.TipoVar == "int16") { this.endColuna = this.endColuna * 2; while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } else { this.endColuna = this.endColuna * 4; while (this.endLinha > 0) { while (this.contInd < this.endColuna) { this.endereco = memoria.AlocaRam(aux.NomeVar); if (this.contInd == 0) { aux.setEndMatriz(this.indMatriz, this.endereco); this.indMatriz++; } this.contInd++; } this.contInd = 0; this.endLinha--; } inst2.Arg1 = aux.NomeVar; inst2.Arg2 = ""; inst2.Op = "declaraVar"; this.triplas.Add(inst2); } }
111
} } } this.TabelaSimbolos[i] = aux; } } } break; //------------------------------------------------- case 71:// gera o fim da rotina instrucao.Arg1 = this.rotina.Pop(); if(instrucao.Arg1 == "main") instrucao.Op = "loopI"; else instrucao.Op = "retorno"; instrucao.Arg2 = ""; this.triplas.Add(instrucao); break; //------------------------------------------------- case 72://obtem o primeiro operando que será usado para gerar a instrução de comparação this.tk = token.getLexeme(); this.var_case = this.tk; this.rotulo_case = gera_regLabel.geraRotulo(); break; //------------------------------------------------- case 73://obtem o segundo operando que será usado na instrução de comparação e gera instrução this.tk = token.getLexeme(); instrucao.Arg1 = this.tk; instrucao.Arg2 = this.var_case; instrucao.Op = "=="; this.triplas.Add(instrucao); break; //------------------------------------------------- case 74://cria label, insere no fluxo do programa e empilha instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "loopC"; this.rotulo.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 75://insere salto incondicional para o fim do bloco switch instrucao.Arg1 = this.rotulo_case; instrucao.Arg2 = ""; instrucao.Op = "loopI"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 76://desempilha label e insere no flxo do programa instrucao.Arg1 = this.rotulo.Pop(); instrucao.Arg2 = ""; instrucao.Op = "label"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 77://insere label que sinaliza o fim do switch no fluxo do programa instrucao.Arg1 = this.rotulo_case; instrucao.Arg2 = ""; instrucao.Op = "label"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 78://gera label de inicio do for instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "label"; this.rotulo_for = instrucao.Arg1; this.triplas.Add(instrucao); break; //------------------------------------------------- case 79://gera salto condicional para o fim do for, empilha rotulo instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "loopC"; this.rotulo.Push(instrucao.Arg1);
112
this.triplas.Add(instrucao); break; //------------------------------------------------- case 80://passo do laço for this.guarda_op = this.op.Pop(); if (this.guarda_op == "++") instrucao.Op = "+"; else instrucao.Op = "-"; instrucao.Arg1 = this.argumentos.Pop(); instrucao.Arg2 = "1"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 81://insere no fluxo salto incodicional para o inicio do for e label que indica o fim do for instrucao.Arg1 = this.rotulo_for; instrucao.Arg2 = ""; instrucao.Op = "loopI"; this.triplas.Add(instrucao); Tripla instrucao2 = new Tripla(); instrucao2.Arg1 = this.rotulo.Pop(); instrucao2.Arg2 = ""; instrucao2.Op = "label"; this.triplas.Add(instrucao2); break; //------------------------------------------------- case 82://cria label que indica o inicio do do-while, insere-o no fluxo e empilha instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "label"; this.rotulo.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 83://gera salto condicional para o inicio do laço do-while, desempilha label instrucao.Arg1 = this.rotulo.Pop(); instrucao.Arg2 = ""; instrucao.Op = "loopC"; this.triplas.Add(instrucao); break; //------------------------------------------------- case 84://gera label que indica o inicio do laço while instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "label"; this.rotulo_while = instrucao.Arg1; this.triplas.Add(instrucao); break; //------------------------------------------------- case 85://gera salto condicional para o fim do laço while instrucao.Arg1 = gera_regLabel.geraRotulo(); instrucao.Arg2 = ""; instrucao.Op = "loopC"; this.rotulo.Push(instrucao.Arg1); this.triplas.Add(instrucao); break; //------------------------------------------------- case 86://gera salto incondicional para o inicio do laço while e insere o label que indica o fim instrucao.Arg1 = this.rotulo_while; instrucao.Arg2 = ""; instrucao.Op = "loopI"; this.triplas.Add(instrucao); Tripla instrucao3 = new Tripla(); instrucao3.Arg1 = this.rotulo.Pop(); instrucao3.Arg2 = ""; instrucao3.Op = "label"; this.triplas.Add(instrucao3); break; } this.flag = false; }
113
/*....................*/ public void GeraAssembly() /*....................*/ { StreamWriter asm = new StreamWriter(@"c:\assembly.psm"); String codigo; codigo = ""; for (int i = 0; i < this.triplas.Count; i++) { if (this.triplas[i].Op == "/" || this.triplas[i].Op == "*") { this.arg1 = this.triplas[i].Arg1; this.arg2 = this.triplas[i].Arg2; if (this.triplas[i].Op == "/") { codigo = gera_instrucao.GeraDivisao(this.arg1, this.arg2); asm.WriteLine(codigo); codigo = ""; } if (this.triplas[i].Op == "*") { codigo = gera_instrucao.GeraMultiplicacao(this.arg1, this.arg2); asm.WriteLine(codigo); codigo = ""; } this.triplas[i + 1].Arg2 = gera_instrucao.Temp; } else { if (this.triplas[i].Op == "=") { for (int i1 = 0; i1 < this.TabelaSimbolos.Count; i1++) { if (this.triplas[i].Arg1 == this.TabelaSimbolos[i1].NomeVar) { this.arg1 = this.triplas[i].Arg1; this.arg2 = this.triplas[i].Arg2; codigo = gera_instrucao.GeraAtribuicao(this.arg1, this.arg2, this.endereco); asm.WriteLine(codigo); codigo = ""; break; } } } else { if (this.triplas[i].Op == "declaraConst") { for (int i1 = 0; i1 < this.TabelaSimbolos.Count; i1++) { if (this.TabelaSimbolos[i1].NomeVar == this.triplas[i].Arg1 && (this.TabelaSimbolos[i1].Constante || this.TabelaSimbolos[i1].LocalizacaoVar)) { codigo = gera_instrucao.GeraConstante(this.triplas[i].Arg1, this.TabelaSimbolos[i1].getEndereco(0)); asm.WriteLine(codigo); codigo = ""; break; } } } else { if (this.triplas[i].Op == "input" || this.triplas[i].Op == "output") { for (int i1 = 0; i1 < this.TabelaSimbolos.Count; i1++) { if (this.TabelaSimbolos[i1].NomeVar == this.triplas[i].Arg2 && (this.TabelaSimbolos[i1].Pino || this.TabelaSimbolos[i1].LocalizacaoVar)) { if (this.TabelaSimbolos[i1].EndPino <= 15) this.var_hex += "0" + Convert.ToString(this.TabelaSimbolos[i1].EndPino, 16); else
114
this.var_hex += Convert.ToString(this.TabelaSimbolos[i1].EndPino, 16); codigo = gera_instrucao.GeraBlocos(this.triplas[i].Arg1, this.var_hex, this.triplas[i].Op); asm.WriteLine(codigo); codigo = ""; this.var_hex = ""; break; } } } else { if (this.triplas[i].Op == "declaraVar") { for (int i1 = 0; i1 < this.TabelaSimbolos.Count; i1++) { if (this.TabelaSimbolos[i1].NomeVar == this.triplas[i].Arg1 && !this.TabelaSimbolos[i1].Rotina) { if (!this.TabelaSimbolos[i1].Dimensao) codigo = gera_instrucao.GeraVariavel(this.TabelaSimbolos[i1].NomeVar, this.TabelaSimbolos[i1].getEndereco(0)); else { if (this.TabelaSimbolos[i].Matriz) gera_instrucao.GeraVariavel(this.TabelaSimbolos[i1].NomeVar, this.TabelaSimbolos[i1].getEndMatriz(0)); } asm.WriteLine(codigo); codigo = ""; break; } } } else { codigo = gera_instrucao.GeraBlocos(triplas[i].Arg1, triplas[i].Arg2, this.triplas[i].Op); asm.WriteLine(codigo); codigo = ""; } } } } } } asm.Flush(); asm.Close(); }
115
C ARQUIVOS DE MEMÓRIA DO PICOBLAZE
Este apêndice apresenta os arquivos VHDL da memória de programa do PicoBlaze que
foram gerados pelo montador KCPSM. Os arquivos de entrada do montador foram produzidos pela
compilação das aplicações do Dalton-Project no compilador desenvolvido.
C.1 SQROOT.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by sqroot.psm -- -- Generated by KCPSM3 Assembler 16Jun2009-03:36:53. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all; -- -- entity sqroot is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end sqroot; -- architecture low_level_definition of sqroot is -- -- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string; attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string; attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string; attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string;
116
attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string; -- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "01089130500F33006300020001000001E0060000E0050000E0010004E0000003"; attribute INIT_01 of ram_1024_x_18 : label is "54190006020801089130501C33006301020001000001C200E202540C00060208"; attribute INIT_02 of ram_1024_x_18 : label is "050004000301E206820162065839501061046005C302E30493206302C201E203"; attribute INIT_03 of ram_1024_x_18 : label is "000000000000000000004000C2034026E5055430030605080408942050333230"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is
117
"0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "00000000000000000000000000000000003BBA9D024D0A4AEA7402BA9D008888"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
118
attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"01089130500F33006300020001000001E0060000E0050000E0010004E0000003", INIT_01 => X"54190006020801089130501C33006301020001000001C200E202540C00060208", INIT_02 => X"050004000301E206820162065839501061046005C302E30493206302C201E203", INIT_03 => X"000000000000000000004000C2034026E5055430030605080408942050333230", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"00000000000000000000000000000000003BBA9D024D0A4AEA7402BA9D008888", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
119
INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE sqroot.vhd -- ------------------------------------------------------------------------------------
C.2 DIVMUL.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by divmul.psm -- -- Generated by KCPSM3 Assembler 16Jun2009-02:40:42. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all; -- -- entity divmul is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end divmul; -- architecture low_level_definition of divmul is -- -- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string; attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string; attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string;
120
attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string; attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string; -- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "018000004006E0018001E0048001580E40056004E0040000E0010001E0000009"; attribute INIT_01 of ram_1024_x_18 : label is "6300020001000001E2025412010E8201D0305819503002060000341064006301"; attribute INIT_02 of ram_1024_x_18 : label is "000000004000C102C00261036002E30393205420000602080108913050233300"; attribute INIT_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is
121
"0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
122
attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "00000000000000000000000000000000000000000E827A9D00B976900E674888"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"018000004006E0018001E0048001580E40056004E0040000E0010001E0000009", INIT_01 => X"6300020001000001E2025412010E8201D0305819503002060000341064006301", INIT_02 => X"000000004000C102C00261036002E30393205420000602080108913050233300", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
123
INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"00000000000000000000000000000000000000000E827A9D00B976900E674888", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE divmul.vhd -- ------------------------------------------------------------------------------------
C.3 NEGREG.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by negcnt.psm -- -- Generated by KCPSM3 Assembler 16Jun2009-03:06:20. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all; -- -- entity negcnt is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end negcnt; -- architecture low_level_definition of negcnt is -- -- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string; attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string;
124
attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string; attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string; attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string; -- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "0000000000000000000000000000000040004002C002800158074028E0000032"; attribute INIT_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is
125
"0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
126
attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "000000000000000000000000000000000000000000000000000000000000F9D8"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"0000000000000000000000000000000040004002C002800158074028E0000032", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
127
INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"000000000000000000000000000000000000000000000000000000000000F9D8", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE negcnt.vhd -- ------------------------------------------------------------------------------------
C.4 CAST.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by cast.psm -- -- Generated by KCPSM3 Assembler 17Jun2009-19:49:00. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all; -- -- entity cast is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end cast; -- architecture low_level_definition of cast is -- -- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string;
128
attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string; attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string; attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string; attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string; -- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "506006000029E70240058601070EE701500C506006000029E0000008E10101FF"; attribute INIT_01 of ram_1024_x_18 : label is "0029E70440178601070EE701501E506006000029E703400E8601070EE7015015"; attribute INIT_02 of ram_1024_x_18 : label is "0000000000000000A000E000C0024000E70540208601070EE701502750600600"; attribute INIT_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is
129
"0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
130
attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "000000000000000000000000000000000000000000A7B6B4EDAD3B6B4EDAD388"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"506006000029E70240058601070EE701500C506006000029E0000008E10101FF", INIT_01 => X"0029E70440178601070EE701501E506006000029E703400E8601070EE7015015", INIT_02 => X"0000000000000000A000E000C0024000E70540208601070EE701502750600600", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
131
INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"000000000000000000000000000000000000000000A7B6B4EDAD3B6B4EDAD388", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE cast.vhd -- ------------------------------------------------------------------------------------
C.5 GCD.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by gcd.psm -- -- Generated by KCPSM3 Assembler 16Jun2009-02:51:42. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all; -- -- entity gcd is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end gcd; -- architecture low_level_definition of gcd is --
132
-- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string; attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string; attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string; attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string; attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string; -- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "4004E003E001D010400FE002E000D010580C501058105010E101010BE000002F"; attribute INIT_01 of ram_1024_x_18 : label is "000000000000000000000000000000000000000000000000000000004000E004"; attribute INIT_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_03 of ram_1024_x_18 : label is
133
"0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
134
attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000EE9E9DD88"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"4004E003E001D010400FE002E000D010580C501058105010E101010BE000002F", INIT_01 => X"000000000000000000000000000000000000000000000000000000004000E004", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
135
INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"0000000000000000000000000000000000000000000000000000000EE9E9DD88", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE gcd.vhd -- ------------------------------------------------------------------------------------
C.6 INT2BIN.VHD -- -- Definition of a single port ROM for KCPSM3 program defined by int2bin.psm -- -- Generated by KCPSM3 Assembler 16Jun2009-03:01:46. -- -- Standard IEEE libraries -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- -- The Unisim Library is used to define Xilinx primitives. It is also used during -- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd -- library unisim; use unisim.vcomponents.all;
136
-- -- entity int2bin is Port ( address : in std_logic_vector(9 downto 0); instruction : out std_logic_vector(17 downto 0); clk : in std_logic); end int2bin; -- architecture low_level_definition of int2bin is -- -- Attributes to define ROM contents during implementation synthesis. -- The information is repeated in the generic map for functional simulation -- attribute INIT_00 : string; attribute INIT_01 : string; attribute INIT_02 : string; attribute INIT_03 : string; attribute INIT_04 : string; attribute INIT_05 : string; attribute INIT_06 : string; attribute INIT_07 : string; attribute INIT_08 : string; attribute INIT_09 : string; attribute INIT_0A : string; attribute INIT_0B : string; attribute INIT_0C : string; attribute INIT_0D : string; attribute INIT_0E : string; attribute INIT_0F : string; attribute INIT_10 : string; attribute INIT_11 : string; attribute INIT_12 : string; attribute INIT_13 : string; attribute INIT_14 : string; attribute INIT_15 : string; attribute INIT_16 : string; attribute INIT_17 : string; attribute INIT_18 : string; attribute INIT_19 : string; attribute INIT_1A : string; attribute INIT_1B : string; attribute INIT_1C : string; attribute INIT_1D : string; attribute INIT_1E : string; attribute INIT_1F : string; attribute INIT_20 : string; attribute INIT_21 : string; attribute INIT_22 : string; attribute INIT_23 : string; attribute INIT_24 : string; attribute INIT_25 : string; attribute INIT_26 : string; attribute INIT_27 : string; attribute INIT_28 : string; attribute INIT_29 : string; attribute INIT_2A : string; attribute INIT_2B : string; attribute INIT_2C : string; attribute INIT_2D : string; attribute INIT_2E : string; attribute INIT_2F : string; attribute INIT_30 : string; attribute INIT_31 : string; attribute INIT_32 : string; attribute INIT_33 : string; attribute INIT_34 : string; attribute INIT_35 : string; attribute INIT_36 : string; attribute INIT_37 : string; attribute INIT_38 : string; attribute INIT_39 : string; attribute INIT_3A : string; attribute INIT_3B : string; attribute INIT_3C : string; attribute INIT_3D : string; attribute INIT_3E : string; attribute INIT_3F : string; attribute INITP_00 : string; attribute INITP_01 : string; attribute INITP_02 : string; attribute INITP_03 : string; attribute INITP_04 : string; attribute INITP_05 : string; attribute INITP_06 : string; attribute INITP_07 : string;
137
-- -- Attributes to define ROM contents during implementation synthesis. -- attribute INIT_00 of ram_1024_x_18 : label is "03004011E3030301580FB030E20202010102810158144108E1010100E00000AA"; attribute INIT_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000040004004E2020200E303"; attribute INIT_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_08 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_09 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_0F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_10 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_11 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_12 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_13 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_14 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_15 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_16 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_17 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_18 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_19 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_1F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_20 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_21 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_22 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_23 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_24 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_25 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_26 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_27 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_28 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
138
attribute INIT_29 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_2F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_30 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_31 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_32 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_33 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_34 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_35 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_36 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_37 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_38 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_39 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3A of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3B of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3C of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3D of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3E of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INIT_3F of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_00 of ram_1024_x_18 : label is "000000000000000000000000000000000000000000000000000003E238C89D88"; attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000"; -- begin -- --Instantiate the Xilinx primitive for a block RAM ram_1024_x_18: RAMB16_S18 --synthesis translate_off --INIT values repeated to define contents for functional simulation generic map ( INIT_00 => X"03004011E3030301580FB030E20202010102810158144108E1010100E00000AA", INIT_01 => X"0000000000000000000000000000000000000000000040004004E2020200E303", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
139
INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_00 => X"000000000000000000000000000000000000000000000000000003E238C89D88", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") --synthesis translate_on port map( DI => "0000000000000000", DIP => "00", EN => '1', WE => '0', SSR => '0', CLK => clk, ADDR => address, DO => instruction(15 downto 0), DOP => instruction(17 downto 16)); -- end low_level_definition; -- ------------------------------------------------------------------------------------ -- -- END OF FILE int2bin.vhd -- ------------------------------------------------------------------------------------