universidade do vale do itajaÍ centro de ciÊncias …siaibib01.univali.br/pdf/caroline farias...

148
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

Upload: others

Post on 07-Apr-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

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.

APÊNDICES

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