Sintetizador de Sons Final
-
Upload
mestredaniel -
Category
Documents
-
view
145 -
download
0
Transcript of Sintetizador de Sons Final
UNIVERSIDADE FEDERAL DO ESPÍRITO SANTO CENTRO TECNOLÓGICO
DEPARTAMENTO DE ENGENHARIA ELÉTRICA PROJETO DE GRADUAÇÃO
IMPLEMENTAÇÃO DE UM SINTETIZADOR DE SONS POLIFÔNICO EM FPGA
DANIEL LUIS COSMO
VITÓRIA – ES AGOSTO/2011
DANIEL LUIS COSMO
IMPLEMENTAÇÃO DE UM SINTETIZADOR DE SONS POLIFÔNICO EM FPGA
Parte manuscrita do Projeto de Graduação do aluno Daniel Luis Cosmo, apresentado ao Departamento de Engenharia Elétrica do Centro Tecnológico da Universidade Federal do Espírito Santo, para obtenção do grau de Engenheiro Eletricista.
VITÓRIA – ES AGOSTO/2011
DANIEL LUIS COSMO
IMPLEMENTAÇÃO DE UM SINTETIZADOR DE SONS POLIFÔNICO EM FPGA
COMISSÃO EXAMINADORA:
______________________________________ Prof ª. Dr ª. Eliete Maria de Oliveira Caldeira Orientadora ______________________________________ Prof. Dr. André Ferreira Examinador ______________________________________ Engenheiro Tobias Colombo Examinador
Vitória - ES, Agosto de 2011
i
AGRADECIMENTOS
Agradeço à Deus por ter me sustentado até aqui.
Aos meus pais, por todo o apoio e incentivo.
À minha namorada, por estar comigo em todos os momentos.
À professora Eliete, pelo acompanhamento, orientação e paciência.
ii
LISTA DE FIGURAS
Figura 1 – Sintetizador analógico Minimoog ............................................................................. 9
Figura 2 - Sintetizador digital Korg ............................................................................................. 10
Figura 3 – Layout do sintetizador virtual Poizone V2 ........................................................ 12
Figura 4 - Comprimento de uma onda ....................................................................................... 16
Figura 5 - Amplitude de uma onda .............................................................................................. 16
Figura 6 - Exemplos de timbres .................................................................................................... 17
Figura 7 - Composição dos timbres............................................................................................. 18
Figura 8 - Escala musical temperada .......................................................................................... 20
Figura 9 - Vista superior da plataforma Nexys2 ................................................................... 21
Figura 10 – Estrutura conceitual da FPGA ............................................................................... 23
Figura 11 - Célula lógica baseada em LUT ............................................................................... 24
Figura 12 - Distribuição dos componentes na Spartan-3E ............................................... 26
Figura 13 - Conector PS2 ................................................................................................................. 27
Figura 14 - Scan codes para teclado PS2 ................................................................................... 28
Figura 15 – Diagrama de tempo dos sinais no barramento PS2 .................................... 28
Figura 16 - Circuito dos conectores periféricos .................................................................... 29
Figura 17 - Pinagem do conector VGA e circuito usado pela Nexys 2 ......................... 30
Figura 18 – Relação entre sinais no scan horizontal ........................................................... 31
Figura 19 - Esquemático do display de 7 segmentos .......................................................... 33
Figura 20 - Diagrama de tempo de um circuito multiplexador para o display de
LED's ......................................................................................................................................................... 33
Figura 21 - Diagrama de blocos de um data path ................................................................. 36
Figura 22 - Diagrama de blocos conceitual de uma FSMD ............................................... 37
Figura 23 – Entradas e saídas do módulo de entrada PS2 ............................................... 38
Figura 24 - Diagrama de estados do módulo de entrada PS2 ......................................... 39
Figura 25 - Entradas e saídas do módulo do modo de operação ................................... 41
Figura 26 - Digrama de estados do módulo do modo de operação .............................. 43
Figura 27 - Entradas e saídas do módulo de memória ....................................................... 54
Figura 28 – Entradas e saídas do módulo de processamento das notas .................... 55
iii
Figura 29 - Máquina de estados do módulo de processamento de notas .................. 57
Figura 30 - Entradas e saídas do modo de modulação ....................................................... 64
Figura 31 - Entradas e saídas do módulo de geração das frequências ....................... 65
Figura 32 - Diagrama de um controlador VGA ....................................................................... 67
Figura 33 – Entradas e saídas do módulo de controle VGA ............................................. 68
Figura 34 - Entradas e saídas do módulo de sincronização VGA ................................... 69
Figura 35 - Entradas e saídas do módulo de geração de pixels ...................................... 72
Figura 36 - Diagrama de um circuito baseado em mapeamento e objetos ............... 73
Figura 37 - Padrão da letra A e conteúdo da ROM ................................................................ 75
Figura 38 - Circuito de geração de texto ................................................................................... 76
Figura 39 - Imagem gerada no modo de operação livre .................................................... 77
Figura 40 - Entradas e saídas do sintetizador de sons ....................................................... 78
Figura 41 - Circuito amplificador somador ............................................................................. 79
Figura 42 - Circuito amplificador somador com filtro passa alta .................................. 80
Figura 43 - Filtro passa baixa ........................................................................................................ 80
Figura 44 - Circuito analógico completo ................................................................................... 82
Figura 45 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída da FPGA ................ 83
Figura 46 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do filtro passa-
baixa .......................................................................................................................................................... 84
Figura 47 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do circuito
somador, vistas separadamente ................................................................................................... 85
Figura 48 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do circuito
somador ................................................................................................................................................... 85
Figura 49 - Foto do circuito analógico ....................................................................................... 86
iv
LISTA DE TABELAS
Tabela 1 - Características da família Spartan-3E .................................................................. 25
Tabela 2 - Legenda do diagrama de estados do módulo do modo de operação ..... 45
Tabela 3 - Próximos estados selecionados por teclas, a partir do estado “escolha"
..................................................................................................................................................................... 45
Tabela 4 - Próximos estados selecionados por teclas, a partir do estado “livre" ... 45
Tabela 5 - Próximos estados selecionados por teclas, a partir do estado
“posicao_gravando" ............................................................................................................................ 46
Tabela 6 - Próximos estados selecionados por teclas, a partir do estado
“vai_escolha" .......................................................................................................................................... 48
Tabela 7 - Próximos estados selecionados por teclas, a partir do estado
“memoria_cheia" .................................................................................................................................. 48
Tabela 8 - Próximos estados selecionados por teclas, a partir do estado
“posicao_lendo" .................................................................................................................................... 48
Tabela 9 - Escolha de modulações ............................................................................................... 49
Tabela 10 – Escolha de mudanças do tempo original ......................................................... 50
Tabela 11 - Padrão de acendimento do display de 7 segmentos ................................... 53
Tabela 12 – Legenda do diagrama de estados do módulo de processamento das
notas .......................................................................................................................................................... 59
Tabela 13 - Frequências geradas pelo sintetizador ............................................................. 64
Tabela 14 - Relatório de utilização da FPGA ........................................................................... 87
v
LISTA DE SIGLAS
CLB – Configurable Logic Block
CRT – Cathode Ray Tube
DCM – Digital Clock Manager
FPGA – Field Programmmable Gate Array
FSM – Finite State Machine
FSMD – Finite State Machine with Data path
I/O – Input / Output
JTAG – Joint Test Action Group
LED – Light-Emitting Diode
LSB – Least Significant Bit
LUT – Look-Up Table
MIDI – Musical Instrument Digital Interface
MSB – Most Significant Bit
PSDRAM – Pseudo-Static Dynamic Random Access Memory
RAM – Random Access Memory
ROM – Read Only Memory
RTL – Register Tranfer Logic
USB – Universal Serial Bus
VGA – Video Graphics Array
VHDL – VHSIC Hardware Languge Description
VHSIC – Very High Speed Integrated Circuit
vi
SUMÁRIO
AGRADECIMENTOS ................................................................................................................................ i
LISTA DE FIGURAS ................................................................................................................................ ii
LISTA DE TABELAS ............................................................................................................................. iv
LISTA DE SIGLAS .................................................................................................................................... v
SUMÁRIO .................................................................................................................................................. vi
RESUMO.................................................................................................................................................. viii
1 INTRODUÇÃO .................................................................................................................................. 9
1.1 Objetivo ........................................................................................................................................ 12
1.2 Estrutura da Monografia ...................................................................................................... 13
1.3 Motivação .................................................................................................................................... 14
2 CONHECIMENTOS MUSICAIS ................................................................................................ 15
2.1 Física dos sons .......................................................................................................................... 15
2.2 Teoria musical........................................................................................................................... 18
3 PLATAFORMA NEXYS2 ............................................................................................................ 21
3.1 Componentes da plataforma .............................................................................................. 22
3.1.1 FPGA Spartan-3E ............................................................................................................. 23
3.1.1.1 Células lógicas baseadas em LUT ..................................................................... 24
3.1.1.2 Macro células ............................................................................................................. 24
3.1.1.3 Arquitetura Spartan-3E ........................................................................................ 25
3.1.2 Conector PS2 ...................................................................................................................... 26
3.1.3 Conectores periféricos .................................................................................................. 29
3.1.4 Conector VGA..................................................................................................................... 30
3.1.5 Display de 7 segmentos ................................................................................................ 32
3.1.6 Porta USB ............................................................................................................................ 34
4 IMPLEMENTACÃO ...................................................................................................................... 35
4.1 Metodologia de programação ............................................................................................ 35
4.2 Módulos do Sintetizador de Sons ..................................................................................... 38
4.2.1 Módulo de entrada PS2 ................................................................................................. 38
4.2.2 Módulo do modo de operação ................................................................................... 40
vii
4.2.3 Módulo de memória ....................................................................................................... 53
4.2.4 Módulo de processamento das notas ..................................................................... 55
4.2.5 Módulo de modulação ................................................................................................... 64
4.2.6 Módulo de geração de frequências .......................................................................... 65
4.2.7 Módulo de controle VGA ............................................................................................... 67
4.2.7.1 Módulo de sincronização VGA ........................................................................... 69
4.2.7.2 Módulo de geração de pixels ............................................................................... 72
4.3 Código vhdl de interligação dos módulos ..................................................................... 78
5 CIRCUITO ANALÓGICO ............................................................................................................. 79
5.1 Esquema do circuito analógico ......................................................................................... 79
5.2 Cálculos dos componentes do circuito........................................................................... 81
6 TESTES E RESULTADOS .......................................................................................................... 83
7 CONCLUSÃO .................................................................................................................................. 88
REFERÊNCIAS ....................................................................................................................................... 89
ANEXOS .................................................................................................................................................... 90
viii
RESUMO
Neste trabalho de graduação será apresentado o processo de criação e
funcionamento de um sintetizador de sons polifônico básico, com entrada
advinda de um teclado de computador com conector PS2, criado via programação
de hardware. O processamento do sintetizador será feito por uma FPGA (Field
Programmable Gate Array), e o mesmo terá algumas funções adicionais como
gravação na memória e leitura da memória com modulação e mudança de tempo.
9
1 INTRODUÇÃO
Sintetizadores de sons são instrumentos musicais eletrônicos capazes de
produzir uma variedade de eventos musicais através da geração e combinação de
diversos sinais sonoros. A evolução dos sintetizadores ocorreu conforme o
progresso da música na história. No decorrer da história da música, a tecnologia e
a ciência têm exercido papel fundamental na superação dos obstáculos técnicos e
na ampliação da capacidade de expressão artística.
A invenção do transistor, no final da década de 1940, trouxe enormes
perspectivas de desenvolvimento à eletrônica, graças à redução de tamanho e de
consumo de potência dos circuitos. Isso viabilizou o desenvolvimento de mais
aplicações musicais, e as pesquisas no campo da síntese sonora foram se
intensificando cada vez mais. Na década de 1960, os sintetizadores entraram no
cenário musical, produzidos comercialmente pelo engenheiro norte-americano
Bob Moog. As sonoridades sintéticas marcaram as décadas seguintes e o
sintetizador consolidou-se definitivamente como instrumento musical [1]. Na
Figura 1 é mostrado um sintetizador analógico criado pelo engenheiro Bob Moog.
Figura 1 – Sintetizador analógico Minimoog [2]
10
Os primeiros sintetizadores usavam circuitos eletrônicos analógicos, e sua
sonoridade característica era obtida a partir de sinais puramente eletrônicos
(forma de onda senoidal, triangular, dente-de-serra, etc.), que não existem
normalmente nos instrumentos acústicos convencionais [1].
Praticamente todos os primeiros sintetizadores analógicos eram
monofônicos, já que só podiam gerar uma frequência sonora de cada vez. Como
cada nota tinha que ser gerada por um circuito eletrônico relativamente
complexo, ficava muito caro e complicado construir um instrumento com
capacidade polifônica e ao mesmo tempo com controle total sobre a síntese do
som. Essa limitação só foi superada com o uso de microprocessadores, no final da
década de 1970 [1].
Com a redução dos preços da tecnologia digital e o aumento da capacidade
dos microprocessadores, a síntese dos sons passou a ser realizada digitalmente, e
não mais por circuitos analógicos. O sintetizador digital evoluiu rapidamente, e
em menos de uma década já se dispunha de instrumentos com boa capacidade
polifônica e inúmeros recursos de controle e expressividade. A qualidade sonora
melhorou bastante, e também passaram a serem usadas amostras digitais
(samples) de sons acústicos, o que permitiu ao sintetizador simular com razoável
realismo muitos instrumentos convencionais [1]. Na Figura 2 pode-se ver um
sintetizador digital da marca Korg.
Figura 2 - Sintetizador digital Korg
11
A evolução dos instrumentos musicais eletrônicos está caminhando agora
para o chamado “instrumento virtual”, implementado totalmente por software
dentro do computador e acionado via MIDI1 por um teclado controlador (externo)
ou por um outro software (sequenciador) no mesmo computador. Tirando
proveito da enorme capacidade de processamento que há nos computadores
modernos, os fabricantes estão migrando seus sintetizadores e samplers para
versões em software. Já existe hoje uma grande variedade de opções, desde os
sintetizadores virtuais que simplesmente reproduzem amostras digitais de
instrumentos acústicos, até os que usam modelagem física para não só simular
instrumentos acústicos (piano, orquestras, etc.), mas também recriar os próprios
sintetizadores analógicos antigos [1]. Na Figura 3 pode-se ver o layout de um
sintetizador virtual.
Os sintetizadores virtuais utilizam o hardware do computador para o seu
processamento, trazendo consigo a necessidade de uma programação bem
apurada e a existência de um processador rápido o suficiente para que a latência
da resposta seja aceitável. O uso de um dispositivo lógico programável, como a
FPGA, para a implementação do sintetizador faz com que a latência da resposta
seja pequena, pois todo o processamento é a nível de hardware. Logo, o clock
necessário para a implementação do sintetizador em uma FPGA é muito menor
do que o clock necessário ao processador que será utilizado para executar o
sintetizador virtual em um computador qualquer.
1 O MIDI (Musical Instrument Digital Interface) é um sistema de comunicação digital para uso com instrumentos e equipamentos musicais. Ele foi criado em 1983 por um grupo de fabricantes, e por isso não existe um proprietário exclusivo dessa tecnologia, que é de domínio público e está disponível para qualquer um que queira implementá-la em seus equipamentos ou softwares
12
Figura 3 – Layout do sintetizador virtual Poizone V2
1.1 Objetivo
O objetivo deste trabalho é a implementação, em uma placa Digilent
contendo uma FPGA, de um sintetizador de sons polifônico, com algumas
especificações dadas abaixo:
1. Os dados de entrada serão advindos de um teclado de computador com
conector PS2, pois a placa Digilent possui uma entrada PS2 exclusiva.
2. Deve haver a possibilidade de se tocar até cinco notas ao mesmo tempo.
3. O sintetizador terá três oitavas musicais para serem tocadas, incluindo
bemóis e sustenidos, e ainda será capaz de gerar uma oitava acima da nota mais
aguda possível de ser tocada e uma oitava abaixo da nota mais grave possível de
ser tocada, para poder gerar todas as modulações possíveis na etapa de leitura da
memória.
4. O sistema apresentará a opção de gravação e leitura em três slots de
memória, constituída pelos block RAM da FPGA.
13
5. Deverá haver a leitura da memória com possibilidade de alterações no
tom e no tempo das notas lidas da memória.
6. O projeto contará com um circuito analógico externo para somar e
amplificar os sinais de saída da placa Digilent.
7. Será usado um alto falante como transdutor de saída do circuito.
8. Uma interface visual será mostrada em um monitor conectado à saída VGA
da placa.
1.2 Estrutura da Monografia
O Capítulo 2 dará uma breve explicação sobre alguns conceitos musicais
básicos para um melhor entendimento do sintetizador proposto.
O Capítulo 3 trará informações sobre o equipamento usado neste projeto: o
kit Nexys2, produzido pela Digilent.
O Capítulo 4 apresentará o programa em si. Cada módulo e suas
interconexões serão explicados detalhadamente.
O Capítulo 5 explicará o funcionamento do circuito analógico externo à
FPGA.
O Capítulo 6 trará testes e resultados do trabalho.
O Capítulo 7 será a conclusão do projeto.
14
1.3 Motivação
Este projeto foi motivado pela afinidade do autor com: a eletrônica digital,
tendo como relevância a linguagem de programação em hardware; o estudo da
música por meio da prática do violino; e como pontapé inicial, a apresentação do
projeto de graduação da aluna Lívia Gerde Muniz [3] ao autor deste projeto.
O projeto proposto em [3] é a criação de um sintetizador de sons
monofônico em FPGA. Algumas das especificações para o projeto do sintetizador
de sons polifônico proposto aqui foram retiradas das sugestões para trabalhos
futuros indicadas em [3].
15
2 CONHECIMENTOS MUSICAIS
O assunto abordado neste capítulo fará com que o leitor tenha um melhor
entendimento do funcionamento do sintetizador proposto.
2.1 Física dos sons
Os sons que ouvimos são produzidos por vibrações no tímpano, que
acontecem quando estas recebem energia de uma onda mecânica. O ouvido
humano é capaz de distinguir frequências entre 20Hz e 20000Hz,
aproximadamente. Uma nota musical nada mais é que um som cuja frequência de
vibração encontra-se dentro do intervalo perceptível pelo ouvido humano.
Os sons podem ser descritos em termos da sua altura, intensidade e timbre.
A altura está ligada à percepção de mais grave e mais agudo. Quanto mais alto é
um som, mais agudo ele é. Esta diferenciação é baseada nas variações da
frequência de vibração das ondas sonoras. Aos sons graves relacionam-se as
baixas frequências e aos agudos as altas frequências. A unidade de frequência é
chamada de Hertz e 1 Hertz equivale a um ciclo completo da onda por segundo
[4]. Na Figura 4 pode-se ver uma demonstração do ciclo completo de uma onda
senoidal, que equivale a um comprimento de onda.
A intensidade de um som está ligada à percepção de mais forte ou mais
fraco. A intensidade está relacionada diretamente com a amplitude de uma onda
sonora, que é o deslocamento máximo a partir da posição de equilíbrio da onda.
Quanto mais intenso é um som, maior é a sua amplitude [4]. Na Figura 5 pode-se
ver uma demonstração da amplitude de uma onda.
16
Figura 4 - Comprimento de uma onda
Figura 5 - Amplitude de uma onda
Quando um som o está incomodando é por estar muito intenso e quando a
pessoa não o está ouvindo é por estar pouco intenso. Um erro comum cometido
pela maioria das pessoas é dizer, nas duas situações anteriores, que o som está
muito alto ou muito baixo. Deve-se lembrar que a altura de um som está
relacionada com a percepção de graves e agudos e não com a intensidade. O certo
seria dizer que o som está muito intenso ou pouco intenso.
Já o timbre está associado à qualidade do som. Ele pode ser comparado a
uma "assinatura" para distinguir sons complexos (formados por uma
superposição de diversos sons relacionados entre si). Sons provenientes de
instrumentos diferentes são perfeitamente distintos, mesmo que eles possuam a
17
mesma frequência e amplitude de onda, uma vez que eles possuem diferentes
"assinaturas". O timbre está associado à série harmônica do som, onde cada nota
musical é composta de uma nota fundamental e uma combinação de harmônicos
superiores com diferentes frequências (múltiplas da frequência fundamental),
diferentes intensidades e diferentes durações [4]. Na Figura 6 observa-se a soma
de duas ondas com timbres e frequências diferentes e na Figura 7 pode-se ver
alguns exemplos de timbres musicais e a relação entre a nota fundamental e seus
harmônicos.
Neste trabalho, as ondas sonoras terão:
- variação de sua altura, no próprio processamento da FPGA;
- variação da sua intensidade, proporcionada pelo amplificador analógico;
- timbre fixo, definido pelo circuito analógico externo à FPGA.
Figura 6 - Exemplos de timbres [4]
18
Figura 7 - Composição dos timbres [4]
2.2 Teoria musical
A um conjunto particular de frequências é estabelecida a definição de notas
musicais. As frequências geradas neste trabalho fazem parte de um conjunto de
notas chamado de “Escala musical temperada” [4]. Essa escala é composta por
doze notas musicais: Dó, Dó#, Ré, Ré#, Mi, Fá, Fá#, Sol, Sol#, Lá, Lá# e Si (o sinal #
tem o nome de “sustenido”). Essas notas se repetem sempre na mesma ordem.
Esse conjunto de doze notas é chamado de oitava e o intervalo de uma nota para a
outra é chamado de semitom. Dois semitons formam um tom.
Na escala musical temperada, quando vamos de uma nota em uma oitava
para a mesma nota na oitava superior, a frequência da onda sonora dobra de
valor. Como uma oitava possui 12 notas, para irmos de uma nota em uma oitava e
chegarmos à mesma nota da oitava superior, devemos percorrer 12 intervalos.
Logo, a escala musical temperada pode ser definida matematicamente como uma
progressão geométrica cujo primeiro termo é a frequência da nota escolhida e
19
cuja razão é o valor numérico
ou 1,0594631 em decorrência da divisão de
uma oitava em 12 intervalos [4].
Assim, se tomarmos a nota Dó0 com a frequência de 32,704 Hz e formos
multiplicando sucessivamente pelo número 1,0594631 vamos obter todas as
frequências das notas musicais da escala musical temperada, culminando com a
primeira nota da oitava seguinte, Dó1, que é o dobro do valor inicial e, portanto
igual a 65,406 Hz.
Na música, modulação é um processo usado para modificar a tonalidade de
um trecho musical ou de uma parte da música. Fazer uma modulação em um
trecho musical corresponde a mudar somente a frequência das notas. Quando
modulamos um trecho da música um tom para cima, todas as notas deste trecho
aumentam sua afinação em um tom, ou dois semitons. Logo, se o trecho musical
contivesse as notas Dó, Ré#, Sol, Fá# e Si, o novo trecho modulado terá as notas
Ré, Fá, Lá, Sol# e Dó#.
Na Figura 8 pode-se ver um total de nove oitavas com todas as suas notas e
frequências associadas. Para o projeto, foram geradas um total de 5 oitavas, desde
o Dó1, com a frequência de 65,406Hz, até o Dó6, com uma frequência de 2093Hz.
Pode-se observar que a frequência da nota Dó6 é igual à frequência da nota Dó1
vezes , pois Dó6 fica exatamente 5 oitavas acima de Dó1. Dessas 5 oitavas
geradas, as 3 do meio são usadas para compor a música e as duas da extremidade
são usadas somente para o caso de uma leitura com modulação, pois se
pudéssemos tocar a nota mais grave ou mais aguda que o sintetizador fosse capaz
de produzir, iríamos encontrar erros na hora de ler essas notas moduladas para
baixo e para cima, respectivamente.
20
Figura 8 - Escala musical temperada [5]
21
3 PLATAFORMA NEXYS2
A Nexys2 é uma plataforma de desenvolvimento de circuitos digitais
completa e pronta para usar, baseada na FPGA Spartan XC3S1200E da Xilinx. Essa
plataforma foi desenvolvida pela Digilent Inc. e é compatível com o software ISE
Design Suíte da Xilinx, o qual será usado para programar tal plataforma. Esse
software foi obtido no site da Xilinx e é uma versão grátis chamada de Web Pack.
Na Figura 9 pode-se ver a vista superior da plataforma Nexys2.
Figura 9 - Vista superior da plataforma Nexys2 [6]
22
3.1 Componentes da plataforma
Os principais componentes e características da plataforma Nexys2 são [9]:
FPGA Spartan-3E XC3S1200E da Xilinx,
entrada USB2 para configuração da placa e transferência de dados em alta
velocidade,
possibilidade de energizar a placa por USB, fonte e baterias,
16 MB de PSDRAM Micron e 16 MB de ROM StrataFlash da Intel,
programação em memória flash para configurações não voláteis da FPGA,
oscilador de 50MHz com socket extra para um segundo oscilador,
60 I/O’s da FPGA roteados para conectores de expansão compostos por um
conector Hirose FX2 de alta velocidade e 4 conectores periféricos,
8 LED’s, display de 7 segmentos com 4 dígitos, 4 botões e 8 switch’s de
deslizamento,
conector VGA,
conector PS2,
conector JTAG para programação e debug.
Além da FPGA Spartan-3E, serão usados no projeto:
- o conector PS2, para a entrada de dados;
- saída do sinal de áudio através de um dos 4 conectores periféricos;
- saída do sinal de vídeo através do conector VGA;
- display de 7 segmentos com 4 dígitos;
- clock advindo do oscilador de 50MHz;
- alimentação e programação através da entrada USB, com o auxílio do programa
Adept da Digilent.
Estes componentes serão explicados nas próximas subseções.
23
3.1.1 FPGA Spartan-3E
A FPGA é um dispositivo lógico que contêm uma matriz de duas dimensões
de células lógicas genéricas e switches programáveis. A estrutura conceitual de
uma FPGA é mostrada na Figura 10. Uma célula lógica pode ser programada para
executar uma função combinacional simples, e um switch programável pode ser
configurado para estabelecer interconexões entre as células. Um design
customizado pode ser implementado especificando a função de cada célula lógica
e seletivamente escolhendo as interconexões feitas pelos switches. Assim que o
design e a síntese do programa estão completos, pode-se usar um cabo adaptador
simples para gravar as células lógicas desejadas e a configuração dos switches na
FPGA, obtendo o circuito customizado. J| que esse processo pode ser feito “no
campo” ao invés de ser feito “em uma f|brica” o dispositivo é conhecido como
programável em campo (Field Programmable) [7].
Figura 10 – Estrutura conceitual da FPGA [7]
24
3.1.1.1 Células lógicas baseadas em LUT
Uma célula lógica usualmente contém um pequeno circuito combinacional
configurável com um flip-flop tipo D (D FF). O método mais comum para
implementar um circuito combinacional configurável é através de uma LUT (look-
up table). Uma LUT de n entradas pode ser considerada como uma memória de
tamanho por 1. Escrevendo o conteúdo dessa memória adequadamente,
podemos usar a LUT para implementar qualquer função combinacional de n
entradas. Na Figura 11 pode-se observar o diagrama conceitual de uma célula
lógica baseada em LUT de 3 entradas e uma implementação da função lógica ou-
exclusivo de 3 entradas [7].
Figura 11 - Célula lógica baseada em LUT [7]
3.1.1.2 Macro células
A maioria das FPGAs possui macro células ou macro blocos. Esses são
fabricados no nível de transistor e suas funcionalidades complementam as células
lógicas gerais. Geralmente macro células incluem blocos de memória,
multiplicadores combinacionais, circuitos de gerenciamento de clock e circuitos
para interface I/O [7].
25
3.1.1.3 Arquitetura Spartan-3E
A arquitetura da família Spartan-3E consiste em cinco elementos
fundamentais [8]:
Blocos lógicos configur|veis (CLB’s – Configurable Logic Blocks) contêm
LUT’s e componentes de armazenamento como flip-flops e latchs. CLB’s
produzem uma grande variedade de funções lógicas como também
armazenam dados.
Blocos de entrada/saída (IOB’s – Input/Output Blocks) controlam o fluxo de
dados entre os pinos de I/O e a lógica interna do dispositivo. Cada IOB
suporta fluxo de dados bidirecional e operações 3-state.
Blocos de RAM (Block RAM) provêem armazenamento de dados na forma
de blocos dual-port de 18Kbits.
Blocos de multiplicação (Multiplier Blocks) aceitam 2 números binários de
18 bits cada como entradas e calculam o resultado.
Blocos digitais de gerenciamento de clocks (DCM – Digital Clock Manager)
fornecem soluções digitais para distribuição, atraso, multiplicação, divisão
e mudança de fase de clocks.
Pode-se ver a distribuição de todos esses elementos na Figura 12 e a Tabela
1 apresenta as características de todas as FPGA’s da família Spartan-3E.
Tabela 1 - Características da família Spartan-3E [8]
26
Figura 12 - Distribuição dos componentes na Spartan-3E [8]
3.1.2 Conector PS2
O conector mini-DIN de 6 pinos presente na Nexys 2 pode acomodar um
mouse ou teclado PS2. A Figura 13 mostra os pinos deste conector. Tanto o
teclado como o mouse usam um barramento serial a dois fios (clock e dados) para
se comunicarem com a FPGA. A comunicação é feita através de uma palavra de 11
bits, que inclui um start bit, 8 bits de dados, um bit de paridade e um stop bit,
nessa ordem [9].
A interface do teclado admite transferência de dados bidirecional para
habilitar a comunicação do host para o teclado (caso o host precise acender algum
LED do teclado), e enquanto não há transferência de dados os sinais de clock e
dados permanecem no estado lógico alto [9]. Neste projeto só será usada a
comunicação do teclado para o host, que será detalhada adiante.
27
Figura 13 - Conector PS2 [9]
Teclados com conector PS2 usam scan codes para comunicar uma tecla
pressionada. A cada tecla é designado um código que é mandado sempre que a
tecla é pressionada. Se a tecla for mantida pressionada, o scan code será mandado
repetidamente a cada 100ms, aproximadamente. Quando uma tecla é liberada, o
código “F0” é mandado, seguido pelo scan code da tecla pressionada. Algumas
teclas, chamadas de teclas estendidas, mandam o código “E0” antes de seu scan
code. Quando tais teclas são liberadas, enviam o código “F0E0” antes do scan code.
O scan code de uma tecla pressionada é chamado de make enquanto o scan code
de uma tecla solta é chamado de break [9]. A Figura 14 mostra os scan codes para
um teclado comum PS2.
O teclado só poderá mandar dados para o host se as linhas de clock e dados
estiverem em nível lógico alto (linhas de clock e dados em nível lógico alto
indicam que o barramento está desocupado, ou idle). Como o host é o “mestre do
barramento”, o teclado deve verificar se o host está mandando dados antes de
usar o barramento. Para facilitar isto, a linha de clock é usada como um sinal
“pronto para enviar” e o teclado tem de checar se a mesma está em nível lógico
alto antes de começar a transferência do scan code. O teclado manda dados para o
host em pacotes de 11 bits, sendo um “start bit” igual a “0”, oito bits de dados
transportando o scan code da tecla (LSB primeiro), seguidos de um bit de
28
paridade ímpar e terminando com um stop bit igual a “1”. O teclado gera 11
transições de clock (com uma frequência variando entre 20kHz a 30kHz) quando
os dados são enviados e o dado é válido para a leitura do host na transição de
descida do clock [9]. A Figura 15 mostra a relação entre os sinais de clock e de
dados.
Figura 14 - Scan codes para teclado PS2 [9]
Figura 15 – Diagrama de tempo dos sinais no barramento PS2 [9]
29
3.1.3 Conectores periféricos
A plataforma Nexys2 fornece quatro conectores com 2 linhas de 6 pinos
cada. Os 4 conectores de 12 pinos contêm 8 sinais para dados, 2 pinos de terra e
dois pinos de tensão positiva cada. Todos os pinos de dados contêm resistores de
proteção contra curto circuito e diodos de proteção ESD (electrostatic discharge).
Um jumper adjacente a cada conector pode conectar o sinal de tensão positiva à
tensão de 3.3V da plataforma Nexys2 ou ao barramento de entrada de energia da
placa [9]. Vários módulos periféricos fabricados pela Digilent podem ser
adaptados aos conectores periféricos. Na Figura 16 pode-se ver o circuito que
interliga os conectores à plataforma.
Figura 16 - Circuito dos conectores periféricos [9]
30
3.1.4 Conector VGA
A plataforma Nexys 2 usa 10 sinais da FPGA para criar uma porta VGA com 8
bits de cor e 2 sinais de sincronização padrões chamado de HS (Horizontal Sync -
sincronização horizontal) e VS (Vertical Sync - sincronização vertical). Dentre os 8
sinais de cor, 3 são usados para a cor vermelha, outros 3 são usados para a cor
verde e os 2 restantes são usados para a cor azul, (o olho humano é menos
sensível a níveis de azul) gerando assim 256 cores possíveis. Na Figura 17 pode-
se ver o circuito usado pela Nexys 2 para fazer a ligação com o conector VGA e a
pinagem do conector [9].
Figura 17 - Pinagem do conector VGA e circuito usado pela Nexys 2 [9]
31
Neste trabalho será usada uma interface para CRT (Cathode Ray Tube) com
resolução de 640 por 480 pixels, com capacidade para 256 cores.
Um monitor CRT funciona da seguinte maneira: um gerador de elétrons gera
um fino feixe de elétrons que viaja em um tubo no vácuo e acerta uma tela
fosforescente. Assim que o feixe de elétrons toca a tela, um ponto luminoso é
emitido. Uma bobina de deflexão horizontal e uma bobina de deflexão vertical,
posicionadas fora do tubo, produzem campos magnéticos que controlam a
direção do feixe de elétrons. Esse feixe de elétrons se move sempre da esquerda
para a direita e de cima para baixo. O circuito interno do monitor gera ondas
dente de serra, controladas pelas entradas HS e VS, que controlam as bobinas de
deflexão [7]. Na Figura 18 pode-se ver a relação entre o sinal HS, a onda dente de
serra que controla a bobina de deflexão horizontal e o scan horizontal.
Figura 18 – Relação entre sinais no scan horizontal [9]
32
Em um monitor CRT colorido, três feixes de elétrons são produzidos e
projetados na tela, produzindo as cores vermelha, verde e azul. Os três pontos de
contato dos feixes com a tela são combinados e formam um pixel. O nível de
voltagem das entradas red, green e blue determina a intensidade de cada feixe e a
cor do pixel.
3.1.5 Display de 7 segmentos
A plataforma Nexys2 contém um display de LED com 4 dígitos. Cada um dos
4 dígitos são formados por 7 segmentos de LED, formando o número “8”. Os
anodos dos 7 LED’s de cada dígito são ligados juntos formando um anodo comum,
mas os catodos dos LED’s continuam separados. Para cada dígito existe um anodo
comum, logo temos 4 anodos comuns que juntos formam 4 entradas do display,
nomeadas de AN0 até AN3. Os catodos de segmentos similares em cada um dos 4
dígitos são conectados juntos e formam 7 sinais de entrada do display de 4
dígitos, nomeados de CA até CG. O LED indicado por DP sinaliza o ponto no lado
inferior direito de cada dígito. Esse esquema de conexões pode ser visto na Figura
19, e cria um display multiplexado no tempo, onde somente um dígito poderá ser
aceso no mesmo instante, pois todos compartilham as mesmas entradas para os
catodos dos LED’s. O dígito a ser aceso ser| selecionado pelas entradas de AN0
até AN3 [9]. As entradas AN0 a AN3 não são ligadas diretamente ao circuito do
display, mas servem como sinais de chaveamento para transistores que enviam
um sinal de 3,3 volts ao circuito.
Um circuito de controle do display pode ser criado para poder mostrar um
número com até 4 dígitos diferentes. Esse circuito energiza os anodos e a
sequência certa de catodos para cada dígito, numa sucessão contínua, com uma
taxa de atualização mais rápida que a percepção do olho humano, que é igual a
60Hz. Cada dígito é iluminado por um quarto do período da taxa de atualização,
mas como o olho humano não detecta essa rápida mudança entre aceso e
apagado, temos a impressão de que os quatro dígitos estão acesos ao mesmo
33
tempo. Tomando como exemplo, se a taxa de atualização for de 800 Hz todo o
display será atualizado em 1,25ms e cada dígito ficará aceso por 0,3125 ms. Na
Figura 20 pode-se ver um diagrama de tempo de um circuito multiplexador.
Figura 19 - Esquemático do display de 7 segmentos [9]
Figura 20 - Diagrama de tempo de um circuito multiplexador para o display de LED's [9]
34
3.1.6 Porta USB
A plataforma Nexys2 inclui uma porta USB2 de alta velocidade baseada no
controlador Cypress CY7C68013A. A porta USB pode ser usada para programar
dispositivos on-board da Xilinx, para transferência de dados a uma velocidade de
38MBytes/s e para energizar a plataforma [9]. Neste trabalho, a conexão PS2 será
usada apenas para programar e energizar a placa. A programação é feita através
do software grátis da Digilent, chamado Adept Suite.
35
4 IMPLEMENTACÃO
Para a implementação do sintetizador, foi usado o programa ISE Design
Suite versão 12.2 da XILINX, parte do Web Pack fornecido pela empresa
gratuitamente em seu site. Para a criação do programa do sintetizador de sons, foi
usada a linguagem de programação de hardware VHDL (VHSIC Hardware
Description Language).
Para o projeto do sintetizador, módulos com funções específicas foram
criados. Essa forma de implementação foi escolhida em razão das seguintes
vantagens:
- facilita a detecção dos erros, pois as funções dos módulos são bem definidas
e distintas;
- facilita a fase de testes, visto que os módulos podem ser verificados
individualmente;
- proporciona mais flexibilidade para melhorias ou modificações, já que a
manutenção é por módulos e não no programa completo;
- permite desenvolvimento independente dos módulos, podendo implementar
e testar funções diferentes ao mesmo tempo;
- facilita a reutilização do programa desenvolvido, visto que um módulo
implementado pode ser utilizado em outros projetos;
- permite uma maior legibilidade da implementação.
4.1 Metodologia de programação
O programa como um todo é considerado como uma FSMD (Finite State
Machine with Data Path – Máquina de estados finita com caminho de dados).
36
Uma FSMD combina uma FSM e circuitos sequenciais regulares. A FSM,
conhecida como control path, examina os comandos externos e gera sinais de
controle que especificam a operação dos circuitos sequenciais, que são
conhecidos como data path. A FSMD é usada para implementar sistemas
descritos pela metodologia RTL (register transfer logic), em que as operações
são especificadas como manipulações de dados e transferência através de uma
coleção de registradores [7].
Uma operação RTL é uma operação que atualiza o próximo valor de um
registrador com base em uma função onde as entradas são os valores atuais de
uma coleção de registradores de dados. Essa função pode ser representada
pela notação f( , ,..., ) onde é o registro de destino, ,
e são os registros de entrada e f( ) é a operação realizada por um
circuito combinacional. O papel da FSM é escolher uma dentre várias opções
de funções que irá atualizar o valor do registrador de dados [7]. Pode-se
enxergar melhor esse papel de controle no diagrama de blocos da Figura 21,
onde um multiplexador escolhe a função baseado no estado atual. Já na Figura
22, pode-se ver um diagrama de blocos conceitual de uma FSMD.
As saídas da FSMD podem ser escolhidas dentre: a FSM, assim como uma
máquina moore e mealy; e o data path, nos valores atuais dos registros, para se
obter uma saída síncrona.
Figura 21 - Diagrama de blocos de um data path [7]
37
Figura 22 - Diagrama de blocos conceitual de uma FSMD [7]
A primeira abordagem ao código de uma FSMD é a de separar o controle da
FSM do controle do data path em partes diferentes do código. Para isso seria
necessário criar vários sinais de controle, que serviriam para controlar o data
path através dos estados da FSM. Em muitas partes deste projeto, para evitar a
utilização de muitos sinais de controle, o código de controle da FSM e do data
path foram escritos juntos, no mesmo process.
Logo, os módulos do programa do sintetizador de sons foram, em geral,
escritos da seguinte maneira: um process sequencial (onde na lista de
sensibilidade constam os sinais de clock e reset somente) contém a atualização de
todos os registros de dados e estados; um process combinacional contém a lógica
de saída do módulo; e um process combinacional contém a lógica do próximo
valor dos registros de estado e de dados, onde em cada estado da FSM se faz a
38
atualização dos registradores de dados referentes a tal estado e a atualização do
próximo estado.
4.2 Módulos do Sintetizador de Sons
Para a construção do sintetizador de sons proposto, foram criados sete
módulos distintos: entrada PS2, modo de operação, memória, processamento de
notas, modulação, geração de frequências e controle VGA, sendo que este último
possui dois sub-módulos que são: sincronização VGA e geração de pixels. Tais
módulos serão apresentados nos tópicos subsequentes.
4.2.1 Módulo de entrada PS2
A função do módulo da entrada PS2 é receber a informação serial vinda do
teclado e fazer a conversão serial-paralela, disponibilizando os bits para serem
usados no resto do programa. Na Figura 23 pode-se identificar as entradas e
saídas do módulo.
Figura 23 – Entradas e saídas do módulo de entrada PS2
39
Os sinais de entrada “clk” e “rst” são, respectivamente, o sinal de clock de 50
MHz da Nexys 2 e o sinal de reset, habilitado por um dos botões da plataforma. Os
sinais “ps2_clk” e “ps2_data” são provenientes do conector PS2. Os sinais de saída
“ps2_out” e “ps2_done_tick” são conectados ao módulo do modo de operação
Como explicado na seção 3.1.2, os bits de dados provenientes do teclado PS2
estão disponíveis na descida do clock, que vem também do teclado. Então é
necessário que se identifique tal descida. A primeira parte da programação do
módulo cria um sinal chamado “fall_edge” que recebe valor lógico ‘1’ sempre que
ocorre essa transição de descida. O registrador “fps2clk_reg” recebe o sinal do
clock do teclado, depois do mesmo ter se mantido estável durante oito ciclos do
clock de 50MHz, filtrando assim o clock do teclado de possíveis ruídos. O sinal
“fall_edge” recebe o valor lógico ‘1’ quando “fps2clk_reg” é igual a ‘1’ e
“fps2clk_next” é igual a ‘0’, caracterizando assim a transição de descida do clock
do teclado.
A FSMD que faz a conversão serial/paralela é constituída de três estados:
“idle”, “data” e “load”. O diagrama de estados da máquina de estados deste
módulo pode ser vista na Figura 24. Enquanto uma condição de transição não for
atendida, o sistema continua no mesmo estado. Estados que possuem setas sem
condições de transição (como a seta de “load” para “idle”) duram somente 1 clock.
idle
data
load
fall_edge=’1’
fall_edge=’1’
e n_reg=’0’
e n_reg=’0’
Figura 24 - Diagrama de estados do módulo de entrada PS2
40
O programa fica no estado “idle” até ser detectada uma transição de descida
do clock do teclado, informando assim que um scan code será transmitido. Após
essa primeira descida de clock, a m|quina vai para o estado “data” e os bits de
dados são postos no registrador “b_reg” de 11 bits, até que todos os 11 bits sejam
transmitidos. A cada bit transmitido, um teste de paridade ímpar é feito. Esse
teste consiste em uma operação ou-exclusivo do novo bit com o resultado da
operação ou-exclusivo anterior e se o resultado final for igual a ‘1’ a transmissão
do pacote passou no teste. No estado “load”, a saída “ps2_done_tick” recebe nível
lógico ‘1’ e caso não haja nenhum erro de start bit, stop bit ou paridade, o
registrador “tecla_reg” recebe os bits de scan code do registrador “b_reg” e o
programa volta para o estado “idle”. O valor do registrador “tecla_reg” é roteado
para a saída “ps2_out”.
É importante observar que a saída “ps2_out” manterá o valor do scan code
atual até outro scan code ser transmitido e a saída “ps2_done_tick” terá valor
lógico ‘1’ somente no período de um clock da FPGA, exatamente um clock antes do
novo scan code estar disponível na saída “ps2_out”. Essas observações serão
importantes para o entendimento do módulo de processamento das notas.
O código em VHDL desse módulo está disponível no anexo A.
4.2.2 Módulo do modo de operação
Este módulo tem como função controlar os modos de operação do
sintetizador de sons, fazer a troca de dados com a memória, enviar dados para os
módulos de processamento de notas e modulação e controlar o display de sete
segmentos. Os modos de operação do sintetizador são:
- livre, onde as notas tocadas são reproduzidas no alto falante;
- gravação, onde as notas são simultaneamente reproduzidas no alto falante e
gravadas na memória;
41
- leitura, onde as notas são lidas da memória e reproduzidas no alto falante.
Na Figura 25 pode-se ver as entradas e saídas do módulo.
Figura 25 - Entradas e saídas do módulo do modo de operação
As entradas “dout_mem1”, “dout_mem2” e “dout_mem3” vêm das 3 unidades
sintetizadas pelo módulo de memória, as entradas “clk” e “rst” vêm da Nexys 2 e
as entradas “ps2_in” e “ps2_done_tick” vêm do módulo de entrada PS2. As saídas
“addr”, “din”, “enable_mem1”, “enable_mem2”, “enable_mem3” e “we” são ligadas
aos módulos de memória, as saídas “processamento_enable”,
“reseta_processamento”, “data_done_tick” e “tecla_out” são ligadas ao módulo de
42
processamento das notas, as saídas “modulação” e “modulação_enable” são
ligadas ao módulo de modulação, as saídas “an” e “sseg” são ligadas ao display de
sete segmentos e a saída “estado” é ligada ao módulo de controle VGA. Todas as
saídas usadas como sinais de enable habilitam seus respectivos módulos no nível
lógico ‘1’.
O módulo do modo de processamento possui uma FSM com 17 estados,
chamados de: “escolha”, “livre”, “posicao_gravando”, “gravando”,
“write_memoria”, “memoria_cheia”, “posicao_lendo”, “modulacao_lendo”,
“tempo_lendo”, “lendo”, “read_memoria”, “novo_tempo1”, “novo_tempo2”,
“novo_tempo3”, “conta_nota”, “vai_escolha” e “reseta_memoria”. Um diagrama
dessa máquina de estados pode ser visto na Figura 26 e sua legenda na Tabela 2.
Enquanto uma condição de transição não for atendida, o sistema continua no
mesmo estado. Estados que possuem setas de saída sem condições de transição
duram somente 1 clock.
A maioria das condições de mudança de estados neste módulo se dá pela
identificação do scan code de uma determinada tecla que foi solta. O registrador
“tecla_reg” recebe os scan codes vindos da entrada “ps2_in” e a identificação da
tecla solta é dada por uma comparação de igualdade do valor atual do registrador
“tecla_reg” com o vetor de bits “11110000” e outra comparação de igualdade do
próximo valor do registrador “tecla_reg” com o scan code da tecla desejada.
43
escolha
livre reseta_memoria 2
1
posicao_gravando
3
1
gravando
write_memoria
4
5
vai_escolha
memoria_cheia
1
1
7
8
posicao_lendo
modulacao_lendo
tempo_lendo
1
1
1
9
10
11
lendo
conta_nota
12
13
14
15
5 16
8
read_memoria
novo_tempo1
novo_tempo2
novo_tempo3
6
Figura 26 - Digrama de estados do módulo do modo de operação
44
1 tecla_next=”01110110” e tecla_reg=”11110000” (tecla esc sendo solta)
2 tecla_next=”00000101” e tecla_reg=”11110000” (tecla F1 sendo solta)
3 tecla_next=”00000110” e tecla_reg=”11110000” (tecla F2 sendo solta)
4 (tecla_next=”00010110” ou tecla_next=”00011110” ou tecla_next=”00100110”) e
tecla_reg=”11110000” (teclas 1, 2 ou 3 sendo soltas)
5 ps2_done_tick=’1’ ou conta_nota_reg=”11111111111” (envio de um novo scan code
pelo teclado ou limite do registrador usado para contar o tempo da nota atingido)
6 tecla_next/=”01110110” (tecla esc não sendo pressionada)
7
(slot_gravacao_reg=”00” e addr1_reg=”11111111111”) ou (slot_gravacao_reg=”01”
e addr2_reg=”11111111111”) ou (slot_gravacao_reg=”10” e addr3_reg=
”11111111111”) (um dos slots de memória chegando ao limite)
8 tecla_next=”01110110” (tecla esc sendo pressionada)
9 tecla_next=”00000100” e tecla_reg=”11110000” (tecla F3 sendo solta)
10 (tecla_next=”00010110” ou tecla_next=”00011110” ou tecla_next=”00100110”) e
tecla_reg=”11110000” (teclas 1, 2 ou 3 sendo soltas)
11
(tecla_next=”01011010” ou tecla_next=”00010101” ou tecla_next=”00011101” ou
tecla_next=”00100100” ou tecla_next=”00101101” ou tecla_next=”00101100” ou
tecla_next=”00110101” ou tecla_next=”00111100” ou tecla_next=”01000011” ou
tecla_next=”01000100” ou tecla_next=”01001101” ou tecla_next=”01010100” ou
tecla_next=”01011011” ou tecla_next=”00011100” ou tecla_next=”00011011” ou
tecla_next=”00100011” ou tecla_next=”00101011” ou tecla_next=”00110100” ou
tecla_next=”00110011” ou tecla_next=”00111011” ou tecla_next=”01000010” ou
tecla_next=”01001011” ou tecla_next=”01001100” ou tecla_next=”01010010” ou
tecla_next=”01011101”) e tecla_reg=”11110000” (uma das teclas a seguir sendo
soltas: Q, W, E, R, T, Y, U, I, O, P, ´, [, A, S, D, F, G, H, J, K, L, Ç, ~, ])
12
(tecla_next=”01011010” ou tecla_next=”00010101” ou tecla_next=”00011101” ou
tecla_next=”00100100” ou tecla_next=”00101101” ou tecla_next=”00101100” ou
tecla_next=”00110101” ou tecla_next=”00111100” ou tecla_next=”01000011” ou
tecla_next=”00011100” ou tecla_next=”00011011” ou tecla_next=”00100011” ou
tecla_next=”00101011” ou tecla_next=”00110100” ou tecla_next=”00110011” ou
tecla_next=”00111011” ou tecla_next=”01000010”) e tecla_reg=”11110000” (uma
das teclas a seguir sendo soltas: Q, W, E, R, T, Y, U, I, A, S, D, F, G, H, J, K)
13 conta_notam_reg=tempo_notam_reg (nota reproduzida por um tempo igual ao que
ela foi gravada, depois de feitas as modificações no tempo solicitadas pelo usuário)
14
(slot_leitura_reg=”00” e laddr1_reg=”00000000000”) ou (slot_leitura_reg=”01” e
laddr2_reg=”00000000000”) ou (slot_leitura_reg=”10” e laddr3_reg=
”00000000000”) (trecho musical referente a memória escolhida completamente
reproduzido)
45
15 tecla_next=”00001100” e tecla_reg=”11110000” (tecla F4 sendo solta)
16 contrst_reg=9999 (contagem de 1 segundo completa)
Tabela 2 - Legenda do diagrama de estados do módulo do modo de operação
O estado “escolha” é o estado inicial da m|quina de estados deste módulo e
através dele pode-se escolher os modos de funcionamento do sintetizador. Nesse
estado a saída “reseta_processamento” recebe o valor lógico ’1’, fazendo com que
o módulo de processamento das notas seja resetado. Existe também a opção de se
apagar a memória através desse estado. Na Tabela 3 pode-se ver todas as opções
de próximos estados e as teclas que levam a cada um deles.
Estado atual Próximo estado Tecla Scan code (hexa)
escolha livre F1 05
escolha posicao_gravando F2 06
escolha posicao_lendo F3 04
escolha reseta_memoria F4 0C
Tabela 3 - Próximos estados selecionados por teclas, a partir do estado “escolha"
No estado “livre” as entradas “ps2_in” e “ps2_done_tick” são roteadas s
saídas “tecla_out” e “data_done_tick” e a saída “processamento_enable” recebe o
valor lógico ‘1’. Com isso, todos os scan codes gerados enquanto neste estado são
processados pelo módulo de processamento das notas, gerando assim
frequências sonoras que irão para o auto-falante. Desse estado, podemos retornar
ao estado “escolha” através da tecla esc, como pode ser visto na Tabela 4.
Estado atual Próximo estado Tecla Scan code (hexa)
livre escolha esc 76
Tabela 4 - Próximos estados selecionados por teclas, a partir do estado “livre"
O estado “posicao_gravando” é usado para a escolha do slot onde a sequência
de scan codes será gravada. O sintetizador possui três slots de memórias, gerados
46
pelo módulo de memória. A Tabela 5 mostra os próximos estados a partir deste
estado e as teclas que levam a eles.
Estado atual Próximo estado Tecla Scan code (hexa) Slot de memória
posicao_gravando escolha esc 76 -
posicao_gravando gravando 1 16 “00”
posicao_gravando gravando 2 2E “01”
posicao_gravando gravando 3 26 “10”
Tabela 5 - Próximos estados selecionados por teclas, a partir do estado “posicao_gravando"
Os estados “gravando” e “write_memoria” fazem parte do modo de operação
de gravação. Nesses estados, as entradas “ps2_in” e “ps2_done_tick” são roteadas
s saídas “tecla_out” e “data_done_tick”, respectivamente, e a saída
“processamento_enable” recebe o valor lógico ‘1’, assim como no estado “livre”,
pois a reprodução e a gravação das notas são feitas simultaneamente.
No processo de gravação todos os scan codes e done ticks gerados pelo
teclado PS2 serão gravados na memória, assim como o tempo de duração de cada
scan code. Na hora da leitura, todos esses dados serão novamente processados
pelo módulo de processamento de notas. Outro método para a gravação seria
gravar as saídas do módulo de processamento das notas, assim não seria preciso
processar os dados novamente, porém este método ocuparia muito mais
memória, pois o módulo de processamento de notas possui 5 saídas de 6 bits
cada, enquanto o módulo do modo de operação possui 9 bits de saída, sendo eles
o scan code e o done tick. Para contar o tempo que um scan code está disponível
no registrador “tecla_reg”, criou-se um clock de 10kHz dado pelo sinal ”tick_10k”,
no intuito de economizar espaço na memória.
A contagem da duração do scan code é feita no estado “gravando” e para
quando a entrada “ps2_done_tick” receber o valor lógico ‘1’, sinalizando a entrada
de um novo scan code, ou o registrador “conta_nota_reg”, usado para a contagem
da nota, chegar ao limite. Se uma dessas duas alternativas acontecer, a máquina
47
de estados vai para o estado “write_memoria”, onde o scan code é gravado na
memória. A segunda alternativa assegura que um scan code possa ficar disponível
por tempo indeterminado, pois sempre que o registrador “conta_nota_reg” chegar
ao limite o scan code será gravado e a contagem recomeçará para o mesmo scan
code.
Sempre que ocorre a mudança do estado “gravando” para o estado
“write_memoria”, o registrador “done_tick_reg” recebe um valor lógico. Esse valor
será igual a ‘1’ quando a entrada “ps2_done_tick” receber valor lógico ‘1’ e igual a
‘0’ quando o registrador “conta_nota_reg” chegar ao limite. Esse registrador
precisa ter 2 bits para poder guardar dois valores de done tick, pois o done tick
que finaliza uma contagem de scan code pertence ao scan code que começará a ser
contado e precisará ser guardado para posterior gravação na memória. O done
tick pertencente ao scan code que será gravado já estará no registrador
“done_tick_reg”.
No estado “write_memoria” uma comparação é feita para saber se a tecla
pressionada no estado anterior foi a tecla esc; se a comparação for positiva a
m|quina de estados vai para o estado “vai_escolha”, caso contr|rio o próximo
estado ser| novamente o estado “gravando”, onde será realizada uma nova
contagem. Ainda nesse estado, o registrador “conta_nota_reg” é resetado e é feita
uma checagem do slot de memória escolhido, então o scan code é gravado na
memória específica junto com o seu tempo de duração e seu done tick (o done tick
possuir| valor lógico ‘0’ se a gravação que está sendo executada aconteceu
porque o registrador usado para contar o scan code chegou ao limite). Caso o
registrador de endereço da memória usada esteja no limite, a máquina de estados
vai para o estado “memoria_cheia”.
No estado “vai_escolha” os registradores “conta_nota_reg” e
“conta_notam_reg”, usados para a contagem da duração das notas na gravação e
leitura, respectivamente, são resetados, bem como os registrador “done_tick_reg”
48
e “mem_tecla_reg”. Quando a tecla esc é solta, o programa vai para o estado
“escolha”, como descrito na Tabela 6.
Estado atual Próximo estado Tecla Scan code (hexa)
vai_escolha escolha esc 76
Tabela 6 - Próximos estados selecionados por teclas, a partir do estado “vai_escolha"
O estado “memoria_cheia” é semelhante ao estado “vai_escolha”. Nele, o
registrador “conta_nota_reg”, usado para a contagem da duração das notas na
gravação, é resetado, bem como o registrador “done_tick_reg”. Quando a tecla esc
é solta, o programa vai para o estado “escolha”, como descrito na Tabela 7.
Estado atual Próximo estado Tecla Scan code (hexa)
memoria_cheia escolha esc 76
Tabela 7 - Próximos estados selecionados por teclas, a partir do estado “memoria_cheia"
O estado “posicao_lendo” é semelhante ao estado “posicao_gravando”. Nele
escolhemos o slot de memória de onde serão lidos os scan codes, como descrito na
Tabela 8. Ainda neste estado os registradores “laddr1_reg”, “laddr2_reg” e
“laddr3_reg”, usados como ponteiros para indicar o endereço no processo de
leitura, recebem os valores dos registradores “addr1_reg”, “addr2_reg” e
“addr3_reg”, usados como ponteiros para indicar o endereço no processo de
gravação. Isso é feito para se preservar os endereços do processo de gravação, e
com isso poder gravar a partir de uma gravação anterior.
Estado atual Próximo estado Tecla Scan code (hexa) Slot de memória
posicao_lendo escolha esc 76 -
posicao_lendo modulacao_lendo 1 16 “00”
posicao_lendo modulacao_lendo 2 2E “01”
posicao_lendo modulacao_lendo 3 26 “10”
Tabela 8 - Próximos estados selecionados por teclas, a partir do estado “posicao_lendo"
49
No estado “modulacao_lendo”, a modulação feita na hora da leitura é
selecionada, de acordo com a Tabela 9.
Estado atual Próximo
estado Tecla
Scan code
(hexa) Modulação
modulacao_lendo escolha esc 76 -
modulacao_lendo tempo_lendo enter 5A Tom original
modulacao_lendo tempo_lendo q 15 Meio tom acima
modulacao_lendo tempo_lendo w 1D Um tom acima
modulacao_lendo tempo_lendo e 24 Um tom e meio acima
modulacao_lendo tempo_lendo r 2D Dois tons acima
modulacao_lendo tempo_lendo t 2C Dois tons e meio acima
modulacao_lendo tempo_lendo y 35 Três tons acima
modulacao_lendo tempo_lendo u 3C Três tons e meio acima
modulacao_lendo tempo_lendo i 43 Quatro tons acima
modulacao_lendo tempo_lendo o 44 Quatro tons e meio acima
modulacao_lendo tempo_lendo p 4D Cinco tons acima
modulacao_lendo tempo_lendo ´ 54 Cinco tons e meio acima
modulacao_lendo tempo_lendo [ 5B Seis tons (uma oitava)
acima
modulacao_lendo tempo_lendo a 1C Meio tom abaixo
modulacao_lendo tempo_lendo s 1B Um tom abaixo
modulacao_lendo tempo_lendo d 23 Um tom e meio abaixo
modulacao_lendo tempo_lendo f 2B Dois tons abaixo
modulacao_lendo tempo_lendo g 34 Dois tons e meio abaixo
modulacao_lendo tempo_lendo h 33 Três tons abaixo
modulacao_lendo tempo_lendo j 3B Três tons e meio abaixo
modulacao_lendo tempo_lendo k 42 Quatro tons abaixo
modulacao_lendo tempo_lendo l 4B Quatro tons e meio abaixo
modulacao_lendo tempo_lendo ç 4C Cinco tons abaixo
modulacao_lendo tempo_lendo ~ 52 Cinco tons e meio abaixo
modulacao_lendo tempo_lendo ] 5D Seis tons (uma oitava)
abaixo
Tabela 9 - Escolha de modulações
50
No estado “tempo_lendo” é escolhida a alteração do tempo das notas no
processo de leitura, de acordo com a Tabela 10.
Estado atual Próximo estado Tecla Scan code (hexa) Novo tempo
tempo_lendo escolha esc 76 -
tempo_lendo lendo enter 5A Tempo original
tempo_lendo lendo q 15 Tempo original *7/8
tempo_lendo lendo w 1D Tempo original *3/4
tempo_lendo lendo e 24 Tempo original *5/8
tempo_lendo lendo r 2D Tempo original *1/2
tempo_lendo lendo t 2C Tempo original *7/16
tempo_lendo lendo y 35 Tempo original *3/8
tempo_lendo lendo u 3C Tempo original *5/16
tempo_lendo lendo i 43 Tempo original *1/4
tempo_lendo lendo a 1C Tempo original *5/4
tempo_lendo lendo s 1B Tempo original *3/2
tempo_lendo lendo d 23 Tempo original *7/4
tempo_lendo lendo f 2B Tempo original *2
tempo_lendo lendo g 34 Tempo original *9/4
tempo_lendo lendo h 33 Tempo original *5/2
tempo_lendo lendo j 3B Tempo original *11/4
tempo_lendo lendo k 42 Tempo original *3
Tabela 10 – Escolha de mudanças do tempo original
Os estados “lendo”, “read_memoria”, “novo_tempo1”, “novo_tempo2”,
“novo_tempo3” e “conta_nota” fazem parte do modo de leitura do sintetizador.
Nesses estados, os registradores “mem_tecla_reg” e “mem_done_tick”, que
recebem os valores de scan code e done tick da memória, respectivamente, são
roteados as saídas “tecla_out” e “data_done_tick”. As saídas
“processamento_enable” e “modulacao_enable” recebem valor lógico ‘1’ para
habilitarem o módulo de processamento de notas e o módulo de modulação e a
saída “modulacao” recebe o valor do registrador “modulacao_reg”, escolhido no
estado “modulacao_lendo”.
51
No estado “lendo”, a saída “addr” recebe o endereço que ser| usado para ler
as informações da memória, dado pela diferença entre os registradores:
“addr1_reg” e “laddr1_reg”, “addr2_reg” e “laddr2_reg”, “addr3_reg” e
“laddr3_reg”, dependendo do slot de leitura escolhido, e ao mesmo tempo habilita
tal slot de memória através das saídas “enable_mem1”, ”enable_mem2” ou
“enable_mem3”. Deste estado o programa vai para o estado “read_memoria”. A
memória funciona de tal maneira que os dados estarão disponíveis na saída da
mesma 1 clock depois de o endereço estar disponível na entrada, pois o processo
de leitura da memória é síncrono.
No estado “read_memoria”, os dados da memória estão disponíveis nas
entradas “dout_mem1”, “dout_mem2” ou “dout_mem3”, dependendo do slot de
memória escolhido. Os registradores “mem_tecla_reg”, “tempo_nota_reg” e o sinal
“mem_done_tick” recebem os dados de scan code, contagem da nota e do done
tick, respectivamente, vindos da memória. É importante observar que, já que
“mem_done_tick” é um sinal, seu valor estar| disponível na saída do módulo um
clock antes do valor de “mem_tecla_reg”, que é um registrador. Desse modo, o
bom funcionamento do módulo de processamento das notas é preservado. Deste
estado o programa vai para o estado “novo_tempo1”.
Os estados “novo_tempo1”, “novo_tempo2” e “novo_tempo3” são
responsáveis pela transformação no tempo da nota, caso seja escolhida alguma
transformação no estado “tempo_lendo”. Duas operações são realizadas no valor
original da nota, sendo uma divisão e uma multiplicação. A divisão é feita no
estado “novo_tempo1” e corresponde a um shift right de n bits nos bits do
registrador “tempo_nota_reg”. Logo, a divisão só funciona para divisões onde o
divisor é do tipo , onde n é um número natural, e o dividendo deve ser definido
como unsigned ou std_logic_vector. A multiplicação é feita no estado
“novo_tempo3” e corresponde a uma multiplicação por um valor constante. Para
a multiplicação ser aceita pelo software usado, o número a ser multiplicado deve
ser definido como integer. Logo, é necessário se fazer uma conversão do
52
registrador “tempo_nota_reg”, de unsigned para integer. Essa conversão é feita no
estado “novo_tempo2”, onde o valor de registrador “tempo_nota_reg”, definido
como unsigned, é passado para o registrador “tempo_notam_reg”, definido como
integer. Os valores usados na divisão e multiplicação dependem do novo tempo
escolhido no estado “tempo_lendo” e equivalem aos valores mostrados na última
coluna da Tabela 10. Após esses 3 estados o programa vai para o estado
“conta_nota”.
No estado “conta_nota” o registrador “conta_notam_reg” é incrementado,
através do sinal “tick_10k”, até possuir o mesmo valor do registrador
“tempo_notam_reg”, que equivale ao tempo modificado do scan code lido da
memória. Assim que os dois registradores anteriores possuírem o mesmo valor, o
valor de um dos registradores “laddr1_reg”, “laddr2_reg” ou “laddr3_reg” é
decrementado, dependendo do slot de memória usado para o processo de leitura,
o registrador “conta_notam_reg” é resetado e o programa vai para o estado
“lendo”, para que outro scan code seja lido da memória. Se um dos registradores
“laddr1_reg”, “laddr2_reg” ou “laddr3_reg”, dependendo do slot de memória
escolhido, apresentar o vetor de bits “0000000000”, o programa vai para o estado
“escolha”, pois significa que a leitura do determinado slot de memória chegou ao
fim. Ainda neste estado, se a tecla esc for pressionada, o programa vai para o
estado “vai_escolha”.
No estado “reseta_memoria” os registradores “addr1_reg”, “addr2_reg” e
“addr3_reg”, usados no processo de gravação, são resetados, fazendo com que o
ponteiro que indica o endereço dos dados nos slots de memória volte para o início
da memória. O programa fica neste estado por 1 segundo, para que a mensagem
indicando o resetamento possa ser lida no monitor, e vai para o estado “escolha”.
O controle do display está localizado no final do módulo do modo de
operação. Como explicado na seção 3.1.5, precisamos escolher uma taxa de
refresh. Essa taxa foi produzida usando-se um contador de 18 bits, incrementado
a cada subida do clock de 50MHz, onde os 2 bits mais significativos são checados
53
para o acendimento de um dos 4 dígitos do display. Logo a taxa de refresh é igual
a
, ou 800Hz.
Os sinais “in0”, “in1”, “in2” e “in3” são roteados saída “sseg”, dependendo
do valor do sinal “sel” que é formado pelos 2 bits mais significativos do
registrador “q_reg”, e os mesmos correspondem ao acendimento dos 4 dígitos do
display de 7 segmentos. Na Tabela 10 podemos ver o formato adquirido por cada
dígito, dependendo do estado do módulo do modo de operação.
Estado Dígito 1 Dígito 2 Dígito 3 Dígito 4
escolha F 0
livre F 1
posicao_gravando F 2 - 1
gravando F 2
posicao_lendo F 3 - 1
modulacao_lendo F 3 - 2
tempo_lendo F 3 - 3
conta_nota F 3
memoria_cheia F U L L
reseta_memoria F 4
Tabela 11 - Padrão de acendimento do display de 7 segmentos
O código deste módulo se encontra no Anexo B.
4.2.3 Módulo de memória
A função do módulo de memória é a criação de uma memória usada para
armazenamento dos scan codes, done ticks e tempo de duração das notas. O
código usado é um modelo para a criação de uma memória RAM single-port
usando-se os block RAM’s disponíveis na FPGA Spartan-3E.
Os block RAM’s podem ser configurados como dual-port e single-port. A
configuração dual-port utiliza duas portas de acesso à memória capazes de
54
realizar operações de leitura e escrita independentemente e ambas têm seu
próprio conjunto de endereço, entrada e saída de dados e sinais de controle. Já a
configuração single-port possui apenas uma porta de acesso à memória também
capaz de realizar operações de leitura e escrita.
A Figura 27 mostra as entradas e saídas deste módulo.
Figura 27 - Entradas e saídas do módulo de memória
As entradas “addr”, “din”, “we” e “enable” vêm do módulo do modo de
operação, a entrada “clk” vem da Nexys 2 e a saída “dout” vai para o módulo do
modo de operação. Foram criadas 3 unidades de memória usando-se este
módulo. A entrada “addr” é utilizada para o endereço, a entrada “din” é a entrada
de dados, as entradas “enable” e “we” são os sinais enable e write enable e a saída
“dout” é a saída de dados.
O tamanho da memória é definido pelas entradas “addr” e “din”, que por sua
vez têm os tamanhos definidos pelas generics “ADDR_WIDTH” e “DATA_WIDTH”,
definidas no código de interligação dos módulos. No caso da memória usada, as
generics “ADDR_WIDTH” e “DATA_WIDTH” possuem um tamanho de 10 bits e
20bits, respectivamente, então a quantidade total de bits usada na memória é
55
dada por bits, ou 9,728Mbits. Ambos os processos de leitura e escrita são
síncronos.
O código em VHDL deste módulo pode ser visto no Anexo C.
4.2.4 Módulo de processamento das notas
A função do módulo de processamento das notas é, através dos scan codes de
cada tecla, distinguir quais teclas são pressionadas e soltas, além de distinguir
quantas teclas estão pressionadas em um determinado instante. Esse módulo
detecta somente cinco teclas pressionadas ao mesmo tempo, sendo que não há
nenhuma interferência no programa se uma tecla além das cinco for pressionada.
Na Figura 28 pode-se identificar as entradas e saídas do módulo.
As entradas “clk” e “rst” vêm da Nexys 2, enquanto as entradas “data_in”,
“ps2_done_tick”, “processamento_enable” e “reseta_processamento” vêm do
módulo do modo de operação. As saídas “freq1”, “freq2”, “freq3”, “freq4” e “freq5”
são ligadas aos módulos de geração de frequências.
Figura 28 – Entradas e saídas do módulo de processamento das notas
56
A FSM do módulo de processamento de notas possui 14 estados, chamados
de: “idle”, “break_idle”, “saida1”, “break_saida1”, “saida2”, “break_saida2”,
“saida3”, “break_saida3”, “saida4”, “break_saida4”, “saida5”, “reset_data”,
“change_data” e “reset”. Pode-se ver na Figura 29 um diagrama da máquina de
estados deste módulo e sua legenda na Tabela 12. Enquanto uma condição de
transição não for atendida, o sistema continua no mesmo estado. Estados que
possuem setas sem condições de transição duram somente 1 clock.
Na figura não foi incluído o estado “reset_data”. Tal estado pode ser acessado
através de todos os estados da máquina, sempre que o sinal
“reseta_processamento” tiver valor lógico ‘1’. Os estados “reset_data” e
“change_data” aparecem várias vezes no diagrama somente para simplificação do
desenho, pois eles são acessados sempre depois dos estados “break_idle”,
“break_saida1”, “break_saida2”, “break_saida3” e “break_saida4”, e levam aos
estados “idle”, “saida1”, “saida2”, “saida3” e “saida4”. Somente um dos dois
estados é acessado e a escolha de qual dos dois estados vai ser acessado depende
da tecla que foi solta. O funcionamento desses estados será explicado mais
adiante.
Os estados “idle”, “saida1”, “saida2”, “saida3”, “saida4” e “saida5” indicam a
quantidade de teclas pressionadas, indo de zero a cinco teclas, respectivamente.
Nesses estados, as saídas são roteadas a um código de seis bits, que depende do
scan code das teclas pressionadas no respectivo estado. Assim, no estado “idle”,
todas as saídas recebem um código padrão, já que nenhuma tecla está sendo
pressionada. No estado “saida1” a saída “freq1” recebe um código indicado pelo
scan code da tecla pressionada nesse estado, enquanto as outras saídas recebem o
código padrão. No estado “saida2” as saídas “freq1” e “freq2” recebem o código
indicado pelo scan code das duas teclas pressionadas nesse estado, enquanto as
outras saídas recebem o código padrão, e assim por diante nos estados “saida3”,
“saida4” e “saida5”.
57
idle
saida1
saida2
saida3
saida4
saida5 break_saida4
break_saida3
break_saida2
break_saida1
break_idle
reset_data
change_data
reset_data
reset_data
change_data
reset_data
change_data
reset_data
change_data
1
2
3
4
5
6
7
8
9
10
11
12
14
15
17
18
20
21
19
13
13
16
16
19
22
22
23
Figura 29 - Máquina de estados do módulo de processamento de notas
58
1 data_next/=data_reg e data_next/=”11110000” (primeira tecla sendo pressionada)
2 data_next/=data_reg e data_next/=”11110000” e data_next=data1_reg e
data_reg=”11110000” (tecla pressionada no estado “saída” 1 sendo solta)
3 data_next/=data_reg e data_next/=”11110000” e (data_next/=data1_reg ou
data_reg/=”11110000”) (segunda tecla sendo pressionada)
4 data_next/=data_reg e data_next/=”11110000” e (data_next=data1_reg ou
data_next=data2_reg) e data_reg=”11110000” (uma das teclas pressionadas no
estado “saída2” sendo solta)
5 data_next/=data_reg e data_next/=”11110000” e ((data_next/=data1_reg e
data_next/=data2_reg) ou data_reg/=”11110000”) (terceira tecla sendo
pressionada)
6 data_next/=data_reg e data_next/=”11110000” e (data_next=data1_reg ou
data_next=data2_reg ou data_next=data3_reg) e data_reg=”11110000” (uma das
teclas pressionadas no estado “saída3” sendo solta)
7 data_next/=data_reg e data_next/=”11110000” e ((data_next/=data1_reg e
data_next/=data2_reg e data_next/=data3_reg) ou data_reg/=”11110000”) (quarta
tecla sendo pressionada)
8 data_next/=data_reg e data_next/=”11110000” e (data_next=data1_reg ou
data_next=data2_reg ou data_next=data3_reg ou data_next=data4_reg) e
data_reg=”11110000” (uma das teclas pressionadas no estado “saída4” sendo
solta)
9 data_next/=data_reg e data_next/=”11110000” e ((data_next/=data1_reg e
data_next/=data2_reg e data_next/=data3_reg e data_next/=data4_reg) ou
data_reg/=”11110000”) (quinta tecla sendo pressionada)
10 (data_next=data1_reg ou data_next=data2_reg ou data_next=data3_reg ou
data_next=data4_reg ou data_next=data5_reg) e data_reg=”11110000” (uma das
teclas pressionadas no estado “saída5” sendo solta)
11 data_reg=data5_reg (tecla solta no estado “saída 5” identificada como sendo a
última tecla pressionada neste estado)
12 data_reg=data1_reg ou data_reg=data2_reg ou data_reg=data3_reg ou
data_reg=data4_reg (tecla solta no estado “saída 5” identificada como não sendo a
última tecla pressionada neste estado)
13 flag_reg=”01111” e ps2_done_tick=’1’ (próximo estado igual a “saída 4” e novo
scan code prestes a ser disponibilizado na entrada)
14 data_reg=data4_reg (tecla solta no estado “saída 4” identificada como sendo a
última tecla pressionada neste estado)
15 data_reg=data1_reg ou data_reg=data2_reg ou data_reg=data3_reg (tecla solta no
estado “saída 4” identificada como não sendo a última tecla pressionada neste
59
estado)
16 flag_reg=”00111” e ps2_done_tick=’1’ (próximo estado igual a “saída 3” e novo
scan code prestes a ser disponibilizado na entrada)
17 data_reg=data3_reg (tecla solta no estado “saída 3” identificada como sendo a
última tecla pressionada neste estado)
18 data_reg=data1_reg ou data_reg=data2_reg (tecla solta no estado “saída 3”
identificada como não sendo a última tecla pressionada neste estado)
19 flag_reg=”00011” e ps2_done_tick=’1’ (próximo estado igual a “saída 2” e novo
scan code prestes a ser disponibilizado na entrada)
20 data_reg=data2_reg (tecla solta no estado “saída 2” identificada como sendo a
última tecla pressionada neste estado)
21 data_reg=data1_reg (tecla solta no estado “saída 2” identificada como não sendo a
última tecla pressionada neste estado)
22 flag_reg=”00001” e ps2_done_tick=’1’ (próximo estado igual a “saída 1” e novo
scan code prestes a ser disponibilizado na entrada)
23 flag_reg=”00000” e ps2_done_tick=’1’ (próximo estado igual a “idle” e novo scan
code prestes a ser disponibilizado na entrada)
Tabela 12 – Legenda do diagrama de estados do módulo de processamento das notas
A transição dos estados funciona da seguinte maneira: o registrador
“data_reg” recebe o scan code advindo do teclado ou da memória e o programa faz
uma comparação de desigualdade do seu valor presente com o seu próximo valor,
além de uma comparação de desigualdade do seu próximo valor com o vetor de
bits “11110000”, que identifica o break de uma nota. Essas comparações podem
ser vistas na condição de transição do estado “idle” para o estado “saida1” na
Figura 29. Se as duas comparações forem positivas, ou seja, se os seus níveis
lógicos forem iguais a ‘1’, significa que um novo scan code de uma tecla foi gerado,
tanto no ato de pressionar quanto no de soltar tal tecla. Para evitar que teclas que
não são relacionadas a notas musicais tenham seu scan code identificado no
módulo, o registrador “data_reg” só recebe valores de scan codes de teclas
relacionadas a notas. Esse registrador só é atualizado se a entrada
“processamento_enable” possuir valor lógico ‘1’, pois em determinadas ocasiões,
60
como na escolha da modulação na leitura de uma música gravada, não se deve
processar tais teclas.
Se tomarmos como exemplo a máquina de estados estando no estado “idle”,
essas duas comparações serão suficientes, pois não há nenhuma tecla
pressionada ainda, e acontecendo dessas duas comparações serem positivas, a
máquina de estados vai para o estado “saída1”, além de guardar o scan code da
tecla pressionada no registrador “data1_reg” e atualizar o registrador “flag_reg”,
que indica quantas notas estão sendo pressionadas.
Estando a máquina de estados no estado “saida1”, o valor do registrador
“data1_reg” é usado para rotear o código de seis bits para a saída “freq1”, e as
duas comparações anteriores são novamente feitas. Caso sejam positivas,
significa que outro scan code foi gerado, mas como já temos uma tecla
pressionada nesse estado precisamos de outras comparações para saber se o
novo scan code foi gerado a partir de uma nova tecla sendo pressionada ou de
uma tecla sendo solta. Nesse caso, o programa faz uma comparação de igualdade
do próximo valor do registrador “data_reg” com o valor do registrador
“data1_reg” e outra comparação de igualdade do valor atual do registrador
“data_reg” e o vetor de bits “11110000”. Se essas duas comparações forem
também positivas significa que o scan code foi gerado por uma tecla que foi solta,
e a máquina de estados vai para o estado “break_idle”. Caso contrário, o scan code
foi gerado por uma nova tecla sendo pressionada, fazendo com que: o novo
estado seja “saida2”, o registrador “data2_reg” receba o valor do novo scan code e
o registrador “flag_reg” seja atualizado. Essa lógica de transição de estados pode
ser estendida para os estados “saida2”, “saida3”, “saida4” e “saida5”.
Os estados com o prefixo break funcionam da seguinte maneira: o
registrador “flag_reg” é atualizado para a quantidade atual de notas pressionadas
e é feita uma comparação de igualdade do registrador “data_reg”, que contém o
scan code da nota solta, com os registradores “data1_reg” a “data5_reg”, para que
se possa distinguir qual nota foi solta. Após a comparação, os registradores
61
“data1_reg” a “data5_reg” são reajustados para conter somente os scan codes das
teclas que continuam sendo pressionadas, e a máquina de estados vai para o
estado “reset_data”, se a tecla solta foi a última tecla pressionada, ou vai para o
estado “change_data”, caso a tecla solta não tenha sido a última tecla pressionada.
Os estados “reset_data” e “change_data” foram criados para resolver dois
problemas encontrados durante a criação deste módulo. O primeiro dos
problemas acontece quando se solta a última tecla pressionada e a pressiona
novamente. Quando a tecla é solta seu scan code fica gravado no registrador
“data_reg” e se a pressionarmos novamente o próximo valor do registrador
“data_reg” receberá o mesmo valor de scan code. Assim, a comparação de
desigualdade do valor atual com o próximo valor do registrador “data_reg” será
negativa e o programa continuará no mesmo estado, ocasionando um erro no
programa. O estado “reset_data” resolve esse problema, resetando o valor do
registrador “data_reg” assim que a última tecla pressionada for solta.
Outro problema encontrado acontece quando se solta uma tecla que não seja
a última tecla pressionada. Nessa ocasião, o registrador “data_reg” recebe o scan
code da tecla solta, mas o scan code da última tecla pressionada continua sendo
enviado a cada 100ms. Isso faz com que a comparação de desigualdade do valor
atual e do próximo valor do registrador “data_reg” seja positiva, fazendo com que
o programa vá para outro estado sem que nenhuma tecla nova seja pressionada.
O estado “change_data” resolve esse problema fazendo com que o registrador
“data_reg” receba o scan code da última tecla pressionada quando soltamos outra
tecla.
Os estados “reset_data” e “change_data” calculam o próximo estado através
do registrador “flag_reg” e a máquina de estados só vai para o próximo estado
quando o sinal “ps2_done_tick” tiver nível lógico ‘1’, exatamente um clock antes
de o novo scan code estar disponível na entrada do módulo. Essa medida deve ser
tomada porque se o programa for para o próximo estado antes de ter o novo scan
code disponível na entrada, o scan code antigo ainda estará disponível na entrada
62
e o programa irá avançar um estado sem que nenhuma tecla seja pressionada,
pois o registrador “data_reg” foi alterado nos estados ”change_data” e
“reset_data”, ocasionando um erro.
O estado “reset_data” funciona exatamente como a entrada “rst”, reiniciando
os valores de todos os registradores e voltando para o estado “idle”.
Na Tabela 13 podemos ver as teclas usadas para gerar frequências sonoras,
assim como os códigos de 6 bits associados a elas. As frequências não
relacionadas às teclas não podem ser tocadas, somente lidas da memória.
Tecla Scan code
(hexa)
Código de 6
bits
Nome da nota
gerada
Frequência da nota
gerada
000000 Dó1 65,406Hz
000001 Dó#1 69,296Hz
000010 Ré1 73,416Hz
000011 Ré#1 77,782Hz
000100 Mi1 82,407Hz
000101 Fá1 87,307Hz
000110 Fá#1 92,499Hz
000111 Sol1 97,999Hz
001000 Sol#1 103,83Hz
001001 Lá1 110,00Hz
001010 Lá#1 116,54Hz
001011 Si1 123,47Hz
q 15 001100 Dó2 130,81Hz
w 1D 001101 Dó#2 138,59Hz
e 24 001110 Ré2 146,83Hz
r 2D 001111 Ré#2 155,56Hz
t 2C 010000 Mi2 164,81Hz
y 35 010001 Fá2 174,61Hz
u 3C 010010 Fá#2 185,00Hz
i 43 010011 Sol2 196,00Hz
o 44 010100 Sol#2 207,65Hz
p 4D 010101 Lá2 220,00Hz
63
´ 54 010110 Lá#2 233,08Hz
[ 5B 010111 Si2 246,94Hz
a 1C 011000 Dó3 261,63Hz
s 1B 011001 Dó#3 277,18Hz
d 23 011010 Ré3 293,66Hz
f 2B 011011 Ré#3 311,13Hz
g 34 011100 Mi3 329,63Hz
h 33 011101 Fá3 349,23Hz
j 3B 011110 Fá#3 369,99Hz
k 42 011111 Sol3 392,00Hz
l 4B 100000 Sol#3 415,30Hz
ç 4C 100001 Lá3 440,00Hz
~ 52 100010 Lá#3 466,16Hz
] 5D 100011 Si3 493,88Hz
\ 61 100100 Dó4 523,25Hz
z 1A 100101 Dó#4 554,37Hz
x 22 100110 Ré4 587,33Hz
c 21 100111 Ré#4 622,25Hz
v 2A 101000 Mi4 659,26Hz
b 32 101001 Fá4 698,46Hz
n 31 101010 Fá#4 739,99Hz
m 3A 101011 Sol4 783,99Hz
, 41 101100 Sol#4 830,61Hz
. 49 101101 Lá4 880,00Hz
; 4A 101110 Lá#4 932,33Hz
/ 51 101111 Si4 987,77Hz
110000 Dó5 1046,5Hz
110001 Dó#5 1108,7Hz
110010 Ré5 1174,7Hz
110011 Ré#5 1244,5Hz
110100 Mi5 1318,5Hz
110101 Fá5 1396,9Hz
110110 Fá#5 1480,0Hz
110111 Sol5 1568,0Hz
111000 Sol#5 1661,2Hz
111001 Lá5 1760,0Hz
111010 Lá#5 1864,7Hz
64
111011 Si5 1975,5Hz
Tabela 13 - Frequências geradas pelo sintetizador
O código em VHDL desse módulo está disponível no anexo D.
4.2.5 Módulo de modulação
A função do módulo de modulação é fazer a modulação do trecho musical no
processo de leitura. Este módulo possui somente lógica combinacional e suas
entradas e saídas podem ser vistas na Figura 30.
Figura 30 - Entradas e saídas do modo de modulação
As entradas “freq1”, “freq2”, “freq3”, “freq4” e “freq5” vêm do módulo de
processamento das notas, as entradas “modulacao” e “modulacao_enable” vêm do
módulo do modo de operação e as saídas “freq_mod1”, “freq_mod2”, “freq_mod3”,
“freq_mod4” e “freq_mod5” vão, cada uma, a uma das cinco unidades criadas pelo
módulo de geração de frequências e também para o módulo de controle VGA.
65
Os códigos de 6 bits provenientes do módulo de processamento das notas só
sofrem modulação caso a entrada “modulacao_enable” seja igual a ‘1’ e os códigos
de 6 bits sejam diferentes de “111111” (códigos iguais a “111111” significam que
não existem teclas pressionadas, pois esse valor é o valor padrão de saída do
módulo de processamento das notas).
Caso as duas condições descritas acima sejam atendidas, a entrada
“modulacao”, que traz o valor da modulação a ser feita, é verificada, os códigos de
6 bits provenientes das entradas “freq1” a “freq5” são incrementados ou
decrementados de acordo com o valor escolhido e são roteados às saídas
“freq_mod1” a “freq_mod5”, respectivamente. Caso a entrada “modulacao_enable”
tenha valor lógico ‘0’ (como é o caso no modo de operação livre), as saídas
recebem o valor das entradas sem alteração.
O código em VHDL deste módulo pode ser visto no Anexo E.
4.2.6 Módulo de geração de frequências
A função do módulo de geração de frequências é gerar frequências de acordo
com a tecla pressionada pelo usuário. As entradas e saídas deste módulo podem
ser vistas na Figura 31.
Figura 31 - Entradas e saídas do módulo de geração das frequências
66
Foram criadas 5 unidades usando o módulo de geração de frequências, logo
existem 5 entradas “nota_in” e 5 saídas “freq_out”. As entradas “nota_in” vêm do
módulo de modulação, as entradas “clk” e “rst” vêm da Nexys 2 e as saídas
“freq_out” são ligadas ao conector periférico JC.
Este módulo possui 61 estados, que são usados para se gerarem as
frequências necessárias ao funcionamento do sintetizador. Os estados
correspondem às notas mostradas na quarta coluna da Tabela 13 mais o estado
“idle”, onde nenhuma frequência é gerada. A transição de estados é controlada
pela entrada “nota_in”, que recebe os códigos de 6 bits gerados no módulo de
processamento das notas e modificados no módulo de modulação. A cada código
existe um estado associado, como pode ser visto na Tabela 13.
Para gerar as frequências usou-se o registrador “count_reg”, que funciona
como um contador, incrementado a cada subida do clock de 50MHz. Para se gerar
uma frequência, o período da onda sonora da nota desejada é dividido em 2 e
então o contador é incrementado durante todo o período, sendo que na primeira
metade do período o registrador “freq_reg” recebe valor lógico ‘0’ e na segunda
metade do período o mesmo registrador recebe valor lógico ‘1’. O registrador
“freq_reg” é roteado saída “freq_out”, caracterizando assim uma onda quadrada
com a frequência desejada. Sempre que a contagem de um período chega ao fim, o
registrador “count_reg” é resetado. Este registrador também é resetado sempre
que a entrada “nota_in” muda seu valor, fazendo com que o registrador j| esteja
resetado quando o programa chegar a um novo estado.
O código em VHDL deste módulo pode ser visto no Anexo F.
67
4.2.7 Módulo de controle VGA
Um circuito controlador de vídeo gera os sinais de sincronização e envia as
saídas que definem a cor dos pixels de modo serial. Um diagrama de blocos
simplificado do controlador de vídeo pode ser visto na Figura 32. Ele contém um
circuito de sincronização e um circuito de geração de pixels.
O circuito de sincronização gera os sinais de sincronização horizontal e
vertical que são ligados diretamente ao conector VGA. Os sinais de sincronização
são gerados através de contadores internos, cujas saídas são os sinais “pixel_x” e
“pixel_y”. Esses sinais indicam as coordenadas atuais do pixel que está sendo
iluminado. O circuito de sincronização ainda gera o sinal “video_on” que indica
onde habilitar e desabilitar o display.
Figura 32 - Diagrama de um controlador VGA [7]
O circuito de geração de pixels gera os oito sinais de cor, que são
coletivamente chamados de RGB, de acordo com as atuais coordenadas do pixel
(indicadas pelos sinais pixel_x e pixel_y) e os sinais externos.
68
As entradas e saídas do módulo de controle VGA podem ser vistas na Figura
33. A entrada “estado” vem do módulo do modo de operação, as entradas
“nota1_mod” a “nota5_mod” vêm do módulo de modulação, as entradas “clk” e
“rst” vêm da plataforma Nexys 2 e as saídas “rgb”, “h_sync” e “v_sync” são ligadas
ao conector VGA.
Além de fazer a ligação dos módulos de sincronização e geração de pixels,
este módulo cria um buffer para o sinal “rgb”, para que ele seja atualizado
juntamente com os sinais “h_sync” e “v_sync”, que também passam por buffers
dentro do módulo de sincronização.
O código em VHDL deste módulo pode ser visto no Anexo G. Os módulos de
sincronização e geração de pixels serão explicados nas próximas subseções.
Figura 33 – Entradas e saídas do módulo de controle VGA
69
4.2.7.1 Módulo de sincronização VGA
O módulo de sincronização VGA gera o sinal h_sync, que especifica o tempo
necessário para se atravessar uma linha, e o sinal v_sync, que especifica o tempo
para se atravessar a tela inteira. A resolução na qual o módulo é baseado é de
640x480 pixels. As entradas e saídas deste módulo podem ser vistas na Figura 34.
As entradas “clk” e “rst” vêm da plataforma Nexys 2, as saídas ”pixel_x”,
“pixel_y” e “vídeo_on” vão para o módulo de geração de pixels, a saída “p_tick” vai
para o módulo de controle VGA e as saídas “h_sync” e “v_sync” são ligadas ao
conector VGA.
Figura 34 - Entradas e saídas do módulo de sincronização VGA
Um período do sinal “h_sync” é o tempo que o feixe de elétrons leva para
varrer uma linha da tela, e esse período contém 800 pixels que podem ser
divididos em 4 regiões:
- Display: região onde os pixels são realmente mostrados na tela. O tamanho dessa
região é de 640 pixels.
70
- Retraço: região onde o feixe de elétrons retorna para o canto esquerdo da tela. O
sinal “video_on” é desabilitado nessa |rea e o seu tamanho é de 96 pixels.
- Fronteira direita: região que forma a fronteira direita da tela. O sinal “video_on”
é desabilitado nessa área e o seu tamanho é de 16 pixels.
- Fronteira esquerda: região que forma a fronteira esquerda da tela. O sinal
“video_on” é desabilitado nessa |rea e o seu tamanho é de 48 pixels.
Um período do sinal “v_sync” é o tempo que o feixe de elétrons leva para
varrer a tela inteira. A unidade de movimento de “v_sync” é representada em
termos de linhas horizontais, e um período contém 525 linhas que podem ser
divididas em 4 regiões:
- Display: região onde as linhas são realmente mostradas na tela. O tamanho
dessa região é de 480 linhas.
- Retraço: região onde o feixe de elétrons retorna para o canto superior esquerdo
da tela. O sinal “video_on” é desabilitado nessa |rea e o seu tamanho é de 2 linhas.
- Fronteira inferior: região que forma a fronteira inferior da tela. O sinal
“video_on” é desabilitado nessa |rea e o seu tamanho é de 10 linhas.
- Fronteira superior: região que forma a fronteira superior da tela. O sinal
“video_on” é desabilitado nessa |rea e o seu tamanho é de 33 linhas.
Todos os valores das regiões mencionadas acima são definidos como
constantes no programa. O diagrama de tempo do scan horizontal pode ser visto
na Figura 18.
A frequência de pixels do circuito é determinada pela multiplicação de três
fatores: o número de pixels em uma linha horizontal, o número de linhas em uma
tela e o número de telas por segundo. Adotando 60 como o número de telas por
segundo, a frequência de pixels é de aproximadamente 25MHz (800 525
60 25,2MHz). O registrador “pixel_tick” é usado para a contagem dos pixels.
71
Seu próximo valor é atualizado a cada clock de 50MHz com o oposto do seu valor
atual, gerando assim um sinal com frequência de 25MHz.
O sinal “h_sync” é obtido através de um contador que conte até 800, dado
pelo registrador “h_count”, e um circuito decodificador. O registrador “h_count”
tem sua contagem incrementada pelo registrador “pixel_tick” e sua contagem é
iniciada no início da região de display, fazendo com que a saída do contador, o
sinal “pixel_x”, seja usada como coordenada do eixo x da região de display. O sinal
“h_sync” recebe o valor ‘0’ apenas na região de retraço, quando o registrador
“h_count” possui seu valor entre 656 e 751.
O sinal “h_end” tem como finalidade marcar o fim da contagem do
registrador “h_count”. Esse sinal é usado para iniciar uma nova contagem no
contador horizontal e incrementar o contador vertical.
O sinal “v_sync” é obtido através de um contador que conte até 525, dado
pelo registrador “v_count”, e um circuito decodificador. O registrador “v_count”
tem sua contagem incrementada pelo sinal “h_end” e sua contagem também é
iniciada no início da região de display, fazendo com que a saída do contador, o
sinal “pixel_y”, seja usada como coordenada y da região de display. O sinal
“v_sync” recebe o valor ‘0’ apenas na região de retraço, quando o registrador
“v_count” possui seu valor igual a 490 ou 491.
O sinal “v_end” tem como finalidade marcar o fim da contagem do
registrador “v_count” e iniciar uma nova contagem no mesmo.
O sinal “video_on” recebe valor lógico ‘1’ apenas na intercessão das regiões
de display do eixo x e do eixo y, para que nada seja desenhado nas fronteiras da
tela. Para evitar glitches, as saídas “h_sync” e “v_sync” passam por buffers,
gerando atraso de um ciclo de clock [7]. Por isso se faz necessário que o sinal
“rgb”, no módulo de controle VGA, também passe por um buffer antes de ser
disponibilizado no conector VGA.
O código em VHDL desse módulo pode ser visto no Anexo H.
72
4.2.7.2 Módulo de geração de pixels
O módulo de geração de pixels tem como função gerar 8 sinais que indicam a
cor de um pixel com base nas coordenadas dadas pelas entradas “pixel_x”,
“pixel_y” e pelos sinais de controle externos. Apesar de possuir o sinal de “clk”
como entrada, esse módulo é combinacional (o sinal de clk é usado na ROM
contendo o padrão das fontes). As entradas e saídas desse módulo podem ser
vistas na Figura 35.
Figura 35 - Entradas e saídas do módulo de geração de pixels
As entradas “pixel_x”, “pixel_y” e “video_on” vêm do módulo de
sincronização VGA, a entrada “clk” vem da plataforma Nexys 2, a entrada “estado”
vem do módulo do modo de operação, as entradas “nota1_mod” a “nota5_mod”
vêm do módulo de modulação e a saída “graph_rgb” é roteada ao conector VGA.
73
Esse módulo foi baseado no esquema de mapeamento de objetos (object-
mapped scheme). O diagrama conceitual de um circuito de geração de pixels
baseado no esquema de mapeamento de objetos pode ser visto na Figura 36.
O diagrama consiste em 3 circuitos de geração de objetos e um circuito de
seleção e roteamento, nomeado de rgb mux. Um circuito de geração de objetos
realiza as seguintes operações:
- Ele contém as coordenadas do objeto (definidas como constantes no
programa) e compara essas coordenadas com a atual localização do scan, dado
pelos sinais “pixel_x” e “pixel_y”.
- Se a atual localização do scan estiver dentro da região do objeto, o circuito
sobe o nível do sinal “objn_on” para ‘1’, indicando que o objeto deve ser
desenhado na tela.
- Especifica a cor do objeto através do sinal “objn_rgb”.
Figura 36 - Diagrama de um circuito baseado em mapeamento e objetos [7]
74
O circuito rgb mux faz a multiplexação de acordo com um esquema de
priorização interna. Ele examina v|rios sinais ”objn_on” e decide qual sinal
“objn_rgb” é roteado para a saída. O esquema de priorização determina qual
objeto vai ser desenhado quando v|rios sinais “objn_on” têm valor ‘1’ ao mesmo
tempo. As entradas externas “estado” e “nota1_mod” a “nota5_mod” são ligadas
ao rgb mux. Essas entradas auxiliam na escolha do sinal “objn_rgb” que vai ser
roteado à saída, fazendo com que o módulo seja capaz de desenhar objetos de
acordo com o estado do módulo do modo de operação e as teclas pressionadas.
Para que as coordenadas possam ser comparadas, os sinais “pix_x” e “pix_y”, do
tipo unsigned, recebem o valor das entradas “pixel_x” e “pixel_y”, do tipo
std_logic_vector. O circuito do rgb mux é sintetizado dentro do único process do
módulo.
Esse esquema foi usado para se desenhar um teclado contendo as 12 teclas
de uma oitava. Esse teclado é mostrado no monitor nos modos: livre, de gravação
e de leitura. Cinco marcas foram desenhadas em cada tecla para indicar a oitava
da nota, já que o sintetizador gera 5 oitavas diferentes. Sempre que uma nota é
tocada, a marcação especificando o tom e a oitava da nota acende no monitor, na
cor vermelha.
O processo de desenhar textos na tela é um pouco mais complexo. Cada letra
possui um padrão que ocupa um espaço de 8 por 16 pixels (8 colunas e 16 linhas).
Os padrões de cada letra e símbolo são guardados em uma ROM e cada padrão
requer 24 x 8 bits. O padrão da letra A pode ser visto na Figura 37. A ROM usada
neste programa foi gerada a partir de uma block RAM da FPGA e contém 128
padrões diferentes, logo o tamanho da memória usada deve ser igual a
27 24 8 bits, ou 211 8 bits.
Dos 11 bits de endereçamento da ROM, os 7 bits mais significativos são
usados para se identificar o padrão desejado e os 4 bits menos significativos são
utilizados para se identificar a linha desejada dentro de um padrão. Todo o
conteúdo da ROM é definido como constante e sua leitura é síncrona, criando um
75
atraso de 1 ciclo de clock. O código em VHDL da ROM é muito parecido com o
código usado no módulo de memória, com a exceção dos sinais de habilitação da
memória e de escrita na memória, que são desnecessários nesse caso. Este código
pode ser visto no anexo J.
Figura 37 - Padrão da letra A e conteúdo da ROM [7]
Usando letras com o tamanho de 8 por 16 pixels numa tela com resolução de
640x480, 80 (640
8) letras podem ser encaixadas em uma linha horizontal e 30 (
480
16)
letras podem ser encaixadas em uma linha vertical. Logo, pode-se tratar a tela
como uma tela de 80 por 30 blocos, onde cada bloco contém uma letra. As letras
podem ser postas na tela usando-se essas coordenadas escaladas.
O funcionamento do circuito de geração de textos envolve dois estágios,
como pode ser visto na Figura 38. No primeiro est|gio, os sinais “pixel_x (9
downto 3)” e “pixel_y (8 downto 4)” fornecem as coordenadas x e y de um
determinado bloco. O circuito de geração de caracteres usa essas coordenadas
76
para gerar o valor desse bloco, dado pelo sinal chamado “char_addr”, que
corresponde a um padrão na ROM. No segundo estágio, o sinal “char_addr” se
transforma nos 7 bits mais significativos de endereçamento da ROM e especifica a
localização do padrão desejado. Esses 7 bits são concatenados com os 4 bits
menos significativos da coordenada y da tela, dados pelo sinal “pixel_y (3 downto
0) e chamado de “row_addr”, formando assim o endereço completo da ROM,
chamado “rom_addr”. A saída da ROM, chamada “font_word”, corresponde a uma
linha de 8 bits do padrão escolhido. Os 3 bits menos significativos da coordenada
x da tela, dados pelo sinal “pixel_x (2 downto 0)” e chamado de “bit_addr”,
especificam a localização do pixel desejado, dado pelo sinal “font_bit”, e um
multiplexador escolhe o bit correspondente ao pixel na saída da ROM.
Figura 38 - Circuito de geração de texto
É possível aumentar o tamanho das fontes fazendo uma operação de shift
right nas coordenadas do pixel e descartando os bits menos significativos que
sobrarem. Como exemplo, pode-se aumentar a fonte de 8 por 16 pixels para uma
fonte de 16 por 32 pixels fazendo com que: os sinais “pixel_x (9 downto 4)” e
“pixel_y (9 downto 5)” forneçam as coordenadas x e y de um determinado bloco
77
para o circuito de geração de caracteres, o sinal “row_addr” seja igual a “pixel_y (4
downto 1)” e o sinal “bit_addr” seja igual a “pixel_x (3 downto 1)”.
Todos os menus e títulos das telas do sintetizador foram gerados com base
no circuito de geração de textos apresentado acima. Para escrever os textos na
tela, o programa primeiro compara a localização atual do scan com as
coordenadas do texto, fazendo com que o sinal “t_(nome do texto)_on” tenha
valor lógico ‘1’. No mux rgb, o sinal “t_(nome do texto)_on” é checado e caso ele
tenha valor lógico ‘1’, a ROM recebe os sinais de endereçamento (“char_addr”,
“row_addr” e “bit_addr”) relativos ao texto e retorna o sinal “font_bit”, que é
checado. Caso seu valor seja ‘1’, a saída “graph_rgb” recebe os bits relativos à cor
do texto, mas caso seu valor seja ‘0’, a saída recebe os bits relativos à cor de fundo.
Os títulos de tela foram desenhados com tamanho de 16 por 32 pixels, na cor
amarela. Já os textos que identificam opções dos menus foram desenhados com
tamanho de 8 por 16 pixels, na cor laranja. A tela gerada no modo de operação
livre pode ser vista na Figura 39.
Figura 39 - Imagem gerada no modo de operação livre
78
O código em VHDL desse módulo pode ser visto no Anexo I.
4.3 Código vhdl de interligação dos módulos
O código de interligação dos módulos tem como função unir todos os
módulos entre si, criando um único programa, o sintetizador de sons polifônico,
onde todas as suas entradas e saídas possam ser acessadas através do kit Nexys2.
As entradas e saídas do sintetizador de sons podem ser vistas na Figura 40. O
código em VHDL pode ser visto no Anexo K.
Figura 40 - Entradas e saídas do sintetizador de sons
As entradas “clk” e “rst” vêm da plataforma Nexys2, as entrada “ps2_clk” e
“ps2_data” vêm do conector PS2, onde um teclado PS2 é conectado. As saídas “an”
e “sseg” vão para o display de 7 segmentos e as saídas “frequencia1”,
“frequencia2”, “frequencia3”, “frequencia4” e “frequencia5” vão, respectivamente,
para os pinos JC1, JC2, JC3, JC4 e JC7, presentes no conector periférico JC.
O arquivo ucf é apresentado no Anexo L.
79
5 CIRCUITO ANALÓGICO
5.1 Esquema do circuito analógico
A principal função do circuito analógico externo à plataforma Nexys 2 é a de
filtrar e somar as 5 frequências de saída da FPGA advindas do conector periférico
JC. Para executar esta operação, um circuito amplificador somador foi usado,
como pode ser visto na Figura 41.
Figura 41 - Circuito amplificador somador
No circuito acima, o potenciômetro R1 funciona como um ajuste de
amplitude da onda de saída, fazendo o papel de controle de volume do
sintetizador.
As saídas da FPGA têm uma amplitude que varia de 0 a 3,3 volts, logo,
possuem um offset de 1,65 volts. Se todas as ondas forem somadas com o offset, a
saída terá um offset dado pela soma dos offsets das ondas de entrada, que é igual a
8,25 volts. Se as tensões de alimentação do amp-op forem pequenas, esse offset
fará com que o amp-op trabalhe saturado, deformando a onda de saída. Para
eliminar o offset, um capacitor foi inserido no circuito somador, em série com as
resistências de entrada, configurando um filtro passa-alta. Esse circuito pode ser
visto na Figura 42.
80
Figura 42 - Circuito amplificador somador com filtro passa alta
Antes de cada entrada do circuito acima um filtro passa baixa foi adicionado.
Esse filtro tem como função transformar o sinal de onda quadrada em triangular
(funcionando como um circuito integrador para frequências acima da frequência
de corte) e reduzir a amplitude proporcionalmente à frequência, deixando a
sensação sonora mais agradável (sons com frequências baixas são percebidas
pelo ouvido humano como tendo menos intensidade do que sons de frequências
médias, para a mesma amplitude de onda). O filtro passa baixa pode ser visto na
Figura 43.
Figura 43 - Filtro passa baixa
81
5.2 Cálculos dos componentes do circuito
O valor do ganho do somador é dado pela fórmula:
Os resistores do circuito somador devem possuir os mesmos valores para
que se ocorra uma adição linear dos 5 sinais, logo os valores de R2, R3, R4, R5 e
R6 são definidos como 100kΩ. A inversão do sinal de saída não influencia na
sonoridade produzida pelos sinais. O potenciômetro R1 é definido como 100kΩ,
fazendo com que o ganho do amplificador somador varie entre 0 e 1.
Os filtros passa-alta possuem uma frequência de corte dada pela fórmula:
=1
2
Usando capacitores iguais a 100ηF, com as resistências iguais a 100kΩ,
teremos uma frequência de corte igual a 15,92Hz. Essa frequência de corte filtra o
offset e não altera em nada o sinal AC da entrada, pois a frequência mínima
gerada no sintetizador é igual a 65,406Hz. Logo, os capacitores C1, C2, C3, C4 e C5
são tem seu valor igual a 100ηF.
O filtro passa-baixa possui dois valores de interesse para o projeto, que são o
ganho e a frequência de corte, dados pelas fórmulas:
=1
2
O ganho do filtro será unitário, logo R1=R2=10kΩ. A frequência de corte foi
escolhida por meio de testes e o capacitor usado foi o de 220ηF, gerando uma
frequência de corte igual a 72,2Hz. O ideal seria que a frequência de corte fosse
menor, para que todas as frequências geradas tenham formato de onda triangular
na saída, mas para frequências de corte menor as notas mais agudas geradas no
sintetizador são quase que totalmente filtradas.
82
O amplificador operacional usado neste projeto é o 741, com alimentação de
mais ou menos 15 volts. O circuito completo com o valor de seus componentes
pode ser visto na Figura 44.
Figura 44 - Circuito analógico completo
83
6 TESTES E RESULTADOS
O circuito analógico foi testado gerando-se as notas Dó1, Dó2 e Dó3 e
analisando-as em alguns pontos importantes do circuito. O primeiro teste foi feito
na saída da FPGA e as formas de onda podem ser vistas na Figura 45. Como
esperado, o sinal possui forma de onda quadrada com amplitude igual a 1,65 volts
e a frequência de um sinal é o dobro da frequência do sinal anterior (o offset foi
retirado nesta medição para melhor visualização da forma de onda).
Figura 45 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída da FPGA
O segundo teste foi feito na saída do circuito passa-baixa e os seus
resultados podem ser vistos na Figura 46.
84
Figura 46 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do filtro passa-baixa
As medições nesse ponto foram feitas com o nível DC para visualização do
offset. Como esperado, as formas de onda anteriormente quadradas foram
transformadas em formas de onda aproximadamente triangulares devido à
integração no tempo dada pelo circuito passa-baixa. Pode-se observar ainda a
redução da amplitude da onda com o aumento da frequência. O offset das ondas é
negativo pois o circuito passa-baixa funciona como um invesor de ganho
inversamente proporcional a frequêcia para frequências na banda de transição.
O terceiro teste foi feito na saída do circuito somador. Na Figura 47, pode-se
ver separadamente as formas de onda das notas geradas. Nota-se que os offsets
das ondas foram eliminados sem qualquer deformação do sinal.
85
Figura 47 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do circuito somador, vistas separadamente
A Figura 48 mostra a forma de onda do sinal na saída do circuito somador
quando as 3 notas são geradas simultaneamente.
Figura 48 - Formas de onda das notas Dó1, Dó2 e Dó3 na saída do circuito somador
86
Na Figura 49 pode-se observar a placa contendo o circuito descrito no
Capítulo 5. A saída do circuito analógico foi conectada a uma caixa de som da
Sony, modelo MBS-100, através de um cabo com conector P2.
Figura 49 - Foto do circuito analógico
A Tabela 14 apresenta o relatório de utilização da FPGA, gerada pelo
software ISE Design Suíte da Xilinx. Ele mostra que a maioria dos blocos lógicos
configuráveis foram usados para o projeto do sintetizador, assim como parte dos
Block RAMs e multiplicadores, o que já era esperado.
87
Tabela 14 - Relatório de utilização da FPGA
88
7 CONCLUSÃO
A proposta para a realização de um sintetizador de sons polifônico foi cumprida
com sucesso. É possível usar o sintetizador proposto como instrumento musical
eletrônico, se assemelhando aos sintetizadores analógicos produzidos antigamente.
Os aprimoramentos em relação à [3] são muitos. Os principais deles são
descritos abaixo:
possibilidade de se tocar até 5 notas ao mesmo tempo,
utilização de bemóis e sustenidos, além da possibilidade de se reproduzir sons
em 5 oitavas diferentes,
inclusão de mais memórias para gravação de músicas,
disponibilidade de modulação na leitura além do aumento na quantidade de
mudanças de tempo disponíveis,
circuito analógico externo com a finalidade de somar os sons e melhorar a
sonoridade,
fácil utilização do sintetizador, com a criação de uma interface visual com todos
os menus e um teclado para auxiliar o usuário.
Mesmo com todos estes aprimoramentos, o sintetizador ainda pode ser
melhorado. Com a utilização de osciladores digitais para a criação de ondas PWM, os
sinais de saída poderiam ter forma de onda senoidal, deixando o som mais agradável.
A possibilidade da escolha de timbres diferentes para a reprodução das notas
também é um importante passo para a melhoria do sintetizador. Além disto, pode-se
estudar o uso de algum protocolo para a comunicação da FPGA com um computador
qualquer, de modo a enviar as músicas gravadas na memória da FPGA para o
computador e até mesmo criar partituras a partir dessas músicas gravadas.
89
REFERÊNCIAS
[1] RATTON, Miguel. Novas tecnologias aplicadas à música, Paraná, outubro de
2006. Disponível em: <http://www.music-
center.com.br/index.php?option=com_content&view=article&id=85:novas-
tecnologias-aplicadas-a-musica-&catid=13:instrumentos&Itemid=5>. Acesso em:
Oito de fevereiro de 2011.
[2] MOOG MUSIC INC. Moog music [internet]. Disponível em:
<www.moogmusic.com>. Acesso em: 29 de fevereiro de 2011.
[3] MUNIZ, Lívia Gerde. Implementação de um sintetizador de sons digital
monofônico em FPGA. Projeto de graduação em engenharia da computação,
universidade federal do Espírito Santo, Vitória, 2009.
[4] SOUZA, Carlos. A física da música [internet]. Disponível em:
<http://www.das.inpe.br/~alex/FisicadaMusica/fismus_introducao.htm>.
Acesso em: 28 de fevereiro de 2011.
[5] NETTO, Luiz. Matemática na música [internet]. Atualizada em 05 de março
de 2006. Disponível em: < http://caraipora2.tripod.com/assuntos.htm>. Acesso
em: 07 de fevereiro de 2011.
[6] DIGILENTINC. Digilent [internet]. Disponível em <www.digilentinc.com>.
Acesso em: 15 de fevereiro de 2011.
[7] CHU, Pong P. FPGA prototyping by VHDL examples. Nova Jersey: John Wiley
& Sons, Inc. 2008.
[8] XILINX. Spartan-3E FPGA Family: Data Sheet. Versão 3.8. Agosto de 2009.
[9] DIGILENTINC. Digilent Nexys2 Board Reference Manual. Junho de 2008.
[10] RATTON, Miguel. Tecnologia dos instrumentos eletrônicos. Áudio Música
e Tecnologia, Rio de Janeiro, edição 119, agosto de 2001.
90
ANEXOS
Anexo A - Código em VHDL do módulo de entrada PS2
Anexo B - Código em VHDL do módulo do modo de operação
Anexo C – Código em VHDL do módulo de memória
Anexo D – Código em VHDL do módulo de processamento das notas
Anexo E – Código em VHDL do módulo de modulação
Anexo F – Código em VHDL do módulo de geração de frequências
Anexo G – Código em VHDL do módulo de controle VGA
Anexo H – Código em VHDL do módulo de sincronização VGA
Anexo I – Código em VHDL do módulo de geração de pixels
Anexo J – Código em VHDL da ROM das fontes
Anexo K – Código em VHDL da interligação dos módulos do sintetizador
Anexo L – Arquivo ucf do sintetizador de sons
91
Anexo A - Código em VHDL do módulo de entrada PS2
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Entrada_ps2 is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
ps2_clk : in STD_LOGIC;
ps2_data : in STD_LOGIC;
ps2_done_tick : out STD_LOGIC;
ps2_out : out STD_LOGIC_VECTOR (7 downto 0));
end Entrada_ps2;
architecture entrada_ps2 of Entrada_ps2 is
type state_type is (idle,data,load);
signal state_reg, state_next : state_type;
signal filter_reg, filter_next : std_logic_vector (7 downto 0);
signal fps2clk_reg, fps2clk_next : std_logic;
signal b_reg, b_next : std_logic_vector (10 downto 0);
signal tecla_reg, tecla_next : std_logic_vector (7 downto 0);
signal n_reg, n_next : unsigned (3 downto 0);
signal paridade_reg, paridade_next : std_logic;
signal fall_edge : std_logic;
begin
--===============================================
--Filtro do clockps2 e criação do sinal fall_edge
--===============================================
--Atualização dos registradores de dados
process(clk,rst)
begin
if rst='1' then
filter_reg <= (others=>'0');
fps2clk_reg <= '0';
elsif (clk'event and clk='1') then
filter_reg <= filter_next;
fps2clk_reg <= fps2clk_next;
end if;
end process;
--Lógica do próximo valor dos registradores de dados e do sinal fall_edge
filter_next <= ps2_clk & filter_reg (7 downto 1);
fps2clk_next <= '1' when filter_reg="11111111" else
'0' when filter_reg="00000000" else
fps2clk_reg;
fall_edge <= fps2clk_reg and (not fps2clk_next);
--================================================================
--Maquina de estados para recebimento dos dados e checagem de erro
--================================================================
--Atualização dos registradores de dados e estados
process(clk,rst)
begin
if rst='1' then
state_reg <= idle;
92
b_reg <= (others=>'0');
n_reg <= (others=>'0');
paridade_reg <= '0';
tecla_reg <= (others=>'0');
elsif (clk'event and clk='1') then
state_reg <= state_next;
b_reg <= b_next;
n_reg <= n_next;
paridade_reg <= paridade_next;
tecla_reg <= tecla_next;
end if;
end process;
--Lógica do próximo valor dos registradores de estado, registradores de dados e saida ps2_done_tick
process(state_reg,n_reg,b_reg,tecla_reg,paridade_reg,fall_edge,ps2_data)
begin
n_next <= n_reg;
b_next <= b_reg;
tecla_next <= tecla_reg;
state_next <= state_reg;
paridade_next <= paridade_reg;
ps2_done_tick <= '0';
case state_reg is
when idle =>
if fall_edge='1' then
b_next <= ps2_data & b_reg (10 downto 1);
n_next <= "1001";
state_next <= data;
paridade_next <= '0';
end if;
when data =>
if fall_edge='1' then
b_next <= ps2_data & b_reg (10 downto 1);
if n_reg=0 then
state_next <= load;
else
n_next <= n_reg - 1;
paridade_next <= (paridade_reg xor ps2_data);
end if;
end if;
when load =>
state_next <= idle;
ps2_done_tick <= '1';
if ((not paridade_reg) and (not b_reg(10)) and (b_reg(0)))='0' then
tecla_next <= b_reg(8 downto 1);
end if;
end case;
end process;
--Lógica da saída ps2_out
ps2_out <= tecla_reg;
end entrada_ps2;
93
Anexo B - Código em VHDL do módulo do modo de operação library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Modo_operacao is
Generic ( ADDR_WIDTH : INTEGER;
DATA_WIDTH : INTEGER);
Port ( clk, rst : in STD_LOGIC;
ps2_in : in STD_LOGIC_VECTOR (7 downto 0);
ps2_done_tick : in STD_LOGIC;
we : out STD_LOGIC;
enable_mem1, enable_mem2, enable_mem3 : out STD_LOGIC;
addr : out STD_LOGIC_VECTOR (ADDR_WIDTH-1 downto 0);
din : out STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
dout_mem1, dout_mem2, dout_mem3 : in STD_LOGIC_VECTOR (DATA_WIDTH-1 downto
0);
processamento_enable : out STD_LOGIC;
reseta_processamento : out STD_LOGIC;
tecla_out : out STD_LOGIC_VECTOR (7 downto 0);
data_done_tick : out STD_LOGIC;
modulacao_enable : out STD_LOGIC;
modulacao : out STD_LOGIC_VECTOR (4 downto 0);
an : out STD_LOGIC_VECTOR (3 downto 0);
sseg : out STD_LOGIC_VECTOR (7 downto 0);
estado : out STD_LOGIC_VECTOR (3 downto 0));
end Modo_operacao;
architecture modo_operacao of Modo_operacao is
constant N : integer :=18;
type state_type is
(escolha,livre,posicao_gravando,gravando,write_memoria,memoria_cheia,posicao_lendo,modulacao_lendo,temp
o_lendo,lendo,read_memoria,novo_tempo1,novo_tempo2,novo_tempo3,conta_nota,vai_escolha,reseta_memoria
);
signal state_reg, state_next : state_type;
signal tecla_reg, tecla_next, mem_tecla_reg, mem_tecla_next : std_logic_vector (7 downto 0);
signal slot_gravacao_reg, slot_gravacao_next, slot_leitura_reg, slot_leitura_next : std_logic_vector (1
downto 0);
signal modulacao_reg, modulacao_next : std_logic_vector (4 downto 0);
signal tempo_reg, tempo_next : std_logic_vector (4 downto 0);
signal cont50k_reg, cont50k_next : integer range 0 to 4999;
signal contrst_reg, contrst_next : integer range 0 to 9999;
signal addr1_reg, addr1_next, addr2_reg, addr2_next, addr3_reg, addr3_next : unsigned
(ADDR_WIDTH-1 downto 0);
signal laddr1_reg, laddr1_next, laddr2_reg, laddr2_next, laddr3_reg, laddr3_next : unsigned
(ADDR_WIDTH-1 downto 0);
signal conta_nota_reg, conta_nota_next : unsigned (DATA_WIDTH-10 downto 0);
signal conta_notam_reg, conta_notam_next : integer range 0 to 2**DATA_WIDTH-8;
signal tempo_nota_reg, tempo_nota_next : unsigned (DATA_WIDTH-10 downto 0);
signal tempo_notam_reg, tempo_notam_next : integer range 0 to 2**DATA_WIDTH-8;
signal done_tick_reg, done_tick_next : std_logic_vector (1 downto 0);
signal mem_done_tick : std_logic;
signal tick_10k : std_logic;
signal in0, in1, in2, in3 : std_logic_vector (7 downto 0);
signal q_reg, q_next : unsigned (N-1 downto 0);
signal sel : std_logic_vector (1 downto 0);
begin
94
--==================================================================
--Geração do clock de 1k para contagem do tempo de duração das notas
--==================================================================
--Atualização do registrador de contagem
process(clk,rst)
begin
if rst='1' then
cont50k_reg <= 0;
elsif (clk'event and clk='1') then
cont50k_reg <= cont50k_next;
end if;
end process;
--Lógica do próximo valor do registrador de contagem e do sinal tick_10k
process(cont50k_reg)
begin
cont50k_next <= cont50k_reg;
tick_10k <= '0';
if cont50k_reg<4999 then
cont50k_next <= cont50k_reg + 1;
else
cont50k_next <= 0;
tick_10k <= '1';
end if;
end process;
--==================================================
--Máquina de estados que controla o modo de operação
--==================================================
--Atualização dos registradores de dados e registrador de estado
process(clk,rst)
begin
if rst='1' then
tecla_reg <= (others=>'1');
mem_tecla_reg <= (others=>'1');
state_reg <= escolha;
slot_gravacao_reg <= "11";
slot_leitura_reg <= "11";
modulacao_reg <= "00000";
tempo_reg <= "00000";
addr1_reg <= (others=>'0');
addr2_reg <= (others=>'0');
addr3_reg <= (others=>'0');
laddr1_reg <= (others=>'0');
laddr2_reg <= (others=>'0');
laddr3_reg <= (others=>'0');
conta_nota_reg <= (others=>'0');
conta_notam_reg <= 0;
tempo_nota_reg <= (others=>'0');
tempo_notam_reg <= 0;
done_tick_reg <= "00";
contrst_reg <= 0;
elsif (clk'event and clk='1') then
tecla_reg <= tecla_next;
mem_tecla_reg <= mem_tecla_next;
state_reg <= state_next;
slot_gravacao_reg <= slot_gravacao_next;
slot_leitura_reg <= slot_leitura_next;
95
modulacao_reg <= modulacao_next;
tempo_reg <= tempo_next;
addr1_reg <= addr1_next;
addr2_reg <= addr2_next;
addr3_reg <= addr3_next;
laddr1_reg <= laddr1_next;
laddr2_reg <= laddr2_next;
laddr3_reg <= laddr3_next;
conta_nota_reg <= conta_nota_next;
conta_notam_reg <= conta_notam_next;
tempo_nota_reg <= tempo_nota_next;
tempo_notam_reg <= tempo_notam_next;
done_tick_reg <= done_tick_next;
contrst_reg <= contrst_next;
end if;
end process;
--Lógica do próximo valor do registrador tecla_reg
tecla_next <= ps2_in;
--Lógica do próximo valor dos registradores de dados, registrador de estado e saídas para o módulo de memória
process(ps2_done_tick,tecla_next,tecla_reg,state_reg,slot_gravacao_reg,slot_leitura_reg,modulacao_reg,t
empo_reg,addr1_reg,addr2_reg,addr3_reg,laddr1_reg,laddr2_reg,laddr3_reg,conta_nota_reg,conta_notam_reg,te
mpo_nota_reg,tempo_notam_reg,dout_mem1,dout_mem2,dout_mem3,mem_tecla_reg,done_tick_reg,contrst_re
g,tick_10k)
begin
state_next <= state_reg;
slot_gravacao_next <= slot_gravacao_reg;
slot_leitura_next <= slot_leitura_reg;
modulacao_next <= modulacao_reg;
tempo_next <= tempo_reg;
addr1_next <= addr1_reg;
addr2_next <= addr2_reg;
addr3_next <= addr3_reg;
laddr1_next <= laddr1_reg;
laddr2_next <= laddr2_reg;
laddr3_next <= laddr3_reg;
conta_nota_next <= conta_nota_reg;
conta_notam_next <= conta_notam_reg;
tempo_nota_next <= tempo_nota_reg;
tempo_notam_next <= tempo_notam_reg;
mem_tecla_next <= mem_tecla_reg;
done_tick_next <= done_tick_reg;
contrst_next <= contrst_reg;
mem_done_tick <= '0';
we <= '0';
enable_mem1 <= '0';
enable_mem2 <= '0';
enable_mem3 <= '0';
din <= (others=>'1');
addr <= (others=>'0');
estado <= "0000";
case state_reg is
when escolha =>
estado <= "0000";
if tecla_next="00000101" and tecla_reg="11110000" then
state_next <= livre;
elsif tecla_next="00000110" and tecla_reg="11110000" then
state_next <= posicao_gravando;
elsif tecla_next="00000100" and tecla_reg="11110000" then
96
state_next <= posicao_lendo;
elsif tecla_next="00001100" and tecla_reg="11110000" then
state_next <= reseta_memoria;
end if;
when livre =>
estado <= "0001";
if tecla_next="01110110" and tecla_reg="11110000" then
state_next <= escolha;
end if;
when posicao_gravando =>
estado <= "0010";
if (tecla_next="00010110" or tecla_next="00011110" or tecla_next="00100110" or
tecla_next="01110110") and tecla_reg="11110000" then
state_next <= gravando;
case tecla_next is
when "01110110" =>
state_next <= escolha;
when "00010110" =>
slot_gravacao_next <= "00";
when "00011110" =>
slot_gravacao_next <= "01";
when "00100110" =>
slot_gravacao_next <= "10";
when others =>
end case;
end if;
when gravando =>
estado <= "0011";
done_tick_next(0) <= '0';
if ps2_done_tick='1' then
state_next <= write_memoria;
done_tick_next(0) <= '1';
elsif conta_nota_reg="11111111111" then
state_next <= write_memoria;
else
if tick_10k='1' then
conta_nota_next <= conta_nota_reg + 1;
end if;
end if;
when write_memoria =>
estado <= "0011";
we <= '1';
if tecla_next="01110110" then
state_next <= vai_escolha;
else
state_next <= gravando;
end if;
conta_nota_next <= (others=>'0');
done_tick_next <= done_tick_reg(0) & '0';
case slot_gravacao_reg is
when "00" =>
if addr1_reg/="1111111111" then
din <= done_tick_reg(1) & tecla_reg &
std_logic_vector(conta_nota_reg);
enable_mem1 <= '1';
addr <= std_logic_vector(addr1_reg);
if state_next=gravando then
addr1_next <= addr1_reg + 1;
end if;
else
97
state_next <= memoria_cheia;
end if;
when "01" =>
if addr2_reg/="1111111111" then
din <= done_tick_reg(1) & tecla_reg &
std_logic_vector(conta_nota_reg);
enable_mem2 <= '1';
addr <= std_logic_vector(addr2_reg);
if state_next=gravando then
addr2_next <= addr2_reg + 1;
end if;
else
state_next <= memoria_cheia;
end if;
when "10" =>
if addr3_reg/="1111111111" then
din <= done_tick_reg(1) & tecla_reg &
std_logic_vector(conta_nota_reg);
enable_mem3 <= '1';
addr <= std_logic_vector(addr3_reg);
if state_next=gravando then
addr3_next <= addr3_reg + 1;
end if;
else
state_next <= memoria_cheia;
end if;
when "11" =>
when others =>
end case;
when memoria_cheia =>
estado <= "0100";
conta_nota_next <= (others=>'0');
done_tick_next <= (others=>'0');
if (tecla_next="01110110" and tecla_reg="11110000") then
state_next <= escolha;
end if;
when posicao_lendo =>
estado <= "0101";
if (tecla_next="00010110" or tecla_next="00011110" or tecla_next="00100110" or
tecla_next="01110110") and tecla_reg="11110000" then
state_next <= modulacao_lendo;
case tecla_next is
when "01110110" =>
state_next <= escolha;
when "00010110" =>
slot_leitura_next <= "00";
laddr1_next <= addr1_reg;
when "00011110" =>
slot_leitura_next <= "01";
laddr2_next <= addr2_reg;
when "00100110" =>
slot_leitura_next <= "10";
laddr3_next <= addr3_reg;
when others =>
end case;
end if;
when modulacao_lendo =>
estado <= "0110";
if (tecla_next="01110110" or tecla_next="01011010" or tecla_next="00010101" or
tecla_next="00011101" or tecla_next="00100100" or tecla_next="00101101" or tecla_next="00101100" or
98
tecla_next="00110101" or tecla_next="00111100" or tecla_next="01000011" or tecla_next="01000100" or
tecla_next="01001101" or tecla_next="01010100" or tecla_next="01011011" or tecla_next="00011100" or
tecla_next="00011011" or tecla_next="00100011" or tecla_next="00101011" or tecla_next="00110100" or
tecla_next="00110011" or tecla_next="00111011" or tecla_next="01000010" or tecla_next="01001011" or
tecla_next="01001100" or tecla_next="01010010" or tecla_next="01011101") and tecla_reg="11110000" then
state_next <= tempo_lendo;
case tecla_next is
when "01110110" =>
state_next <= escolha;
when "01011010" =>
modulacao_next <= "00000";
when "00010101" =>
modulacao_next <= "00001";
when "00011101" =>
modulacao_next <= "00010";
when "00100100" =>
modulacao_next <= "00011";
when "00101101" =>
modulacao_next <= "00100";
when "00101100" =>
modulacao_next <= "00101";
when "00110101" =>
modulacao_next <= "00110";
when "00111100" =>
modulacao_next <= "00111";
when "01000011" =>
modulacao_next <= "01000";
when "01000100" =>
modulacao_next <= "01001";
when "01001101" =>
modulacao_next <= "01010";
when "01010100" =>
modulacao_next <= "01011";
when "01011011" =>
modulacao_next <= "01100";
when "00011100" =>
modulacao_next <= "01101";
when "00011011" =>
modulacao_next <= "01110";
when "00100011" =>
modulacao_next <= "01111";
when "00101011" =>
modulacao_next <= "10000";
when "00110100" =>
modulacao_next <= "10001";
when "00110011" =>
modulacao_next <= "10010";
when "00111011" =>
modulacao_next <= "10011";
when "01000010" =>
modulacao_next <= "10100";
when "01001011" =>
modulacao_next <= "10101";
when "01001100" =>
modulacao_next <= "10110";
when "01010010" =>
modulacao_next <= "10111";
when "01011101" =>
modulacao_next <= "11000";
when others =>
99
end case;
end if;
when tempo_lendo =>
estado <= "0111";
if (tecla_next="01110110" or tecla_next="01011010" or tecla_next="00010101" or
tecla_next="00011101" or tecla_next="00100100" or tecla_next="00101101" or tecla_next="00101100" or
tecla_next="00110101" or tecla_next="00111100" or tecla_next="01000011" or tecla_next="00011100" or
tecla_next="00011011" or tecla_next="00100011" or tecla_next="00101011" or tecla_next="00110100" or
tecla_next="00110011" or tecla_next="00111011" or tecla_next="01000010") and tecla_reg="11110000" then
state_next <= lendo;
case tecla_next is
when "01110110" =>
state_next <= escolha;
when "01011010" =>
tempo_next <= "00000";
when "00010101" =>
tempo_next <= "00001";
when "00011101" =>
tempo_next <= "00010";
when "00100100" =>
tempo_next <= "00011";
when "00101101" =>
tempo_next <= "00100";
when "00101100" =>
tempo_next <= "00101";
when "00110101" =>
tempo_next <= "00110";
when "00111100" =>
tempo_next <= "00111";
when "01000011" =>
tempo_next <= "01000";
when "00011100" =>
tempo_next <= "01001";
when "00011011" =>
tempo_next <= "01010";
when "00100011" =>
tempo_next <= "01011";
when "00101011" =>
tempo_next <= "01100";
when "00110100" =>
tempo_next <= "01101";
when "00110011" =>
tempo_next <= "01110";
when "00111011" =>
tempo_next <= "01111";
when "01000010" =>
tempo_next <= "10000";
when others =>
end case;
end if;
when lendo =>
estado <= "1000";
state_next <= read_memoria;
case slot_leitura_reg is
when "00" =>
addr <= std_logic_vector(addr1_reg-laddr1_reg);
enable_mem1 <= '1';
when "01" =>
addr <= std_logic_vector(addr2_reg-laddr2_reg);
enable_mem2 <= '1';
100
when "10" =>
addr <= std_logic_vector(addr3_reg-laddr3_reg);
enable_mem3 <= '1';
when "11" =>
when others =>
end case;
when read_memoria =>
estado <= "1000";
state_next <= novo_tempo1;
case slot_leitura_reg is
when "00" =>
mem_done_tick <= dout_mem1(DATA_WIDTH-1);
mem_tecla_next <= dout_mem1(DATA_WIDTH-2 downto
DATA_WIDTH-9);
tempo_nota_next <= unsigned(dout_mem1(DATA_WIDTH-10
downto 0));
when "01" =>
mem_done_tick <= dout_mem2(DATA_WIDTH-1);
mem_tecla_next <= dout_mem2(DATA_WIDTH-2 downto
DATA_WIDTH-9);
tempo_nota_next <= unsigned(dout_mem2(DATA_WIDTH-10
downto 0));
when "10" =>
mem_done_tick <= dout_mem3(DATA_WIDTH-1);
mem_tecla_next <= dout_mem3(DATA_WIDTH-2 downto
DATA_WIDTH-9);
tempo_nota_next <= unsigned(dout_mem3(DATA_WIDTH-10
downto 0));
when "11" =>
when others =>
end case;
when novo_tempo1 =>
estado <= "1000";
state_next <= novo_tempo2;
case tempo_reg is
when "00000" =>
tempo_nota_next <= tempo_nota_reg;
when "00001" =>
tempo_nota_next <= "000" & tempo_nota_reg(DATA_WIDTH-10
downto 3);
when "00010" =>
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "00011" =>
tempo_nota_next <= "000" & tempo_nota_reg(DATA_WIDTH-10
downto 3);
when "00100" =>
tempo_nota_next <= "0" & tempo_nota_reg(DATA_WIDTH-10
downto 1);
when "00101" =>
tempo_nota_next <= "0000" & tempo_nota_reg(DATA_WIDTH-10
downto 4);
when "00110" =>
tempo_nota_next <= "000" & tempo_nota_reg(DATA_WIDTH-10
downto 3);
when "00111" =>
tempo_nota_next <= "0000" & tempo_nota_reg(DATA_WIDTH-10
downto 4);
when "01000" =>
101
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "01001" =>
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "01010" =>
tempo_nota_next <= "0" & tempo_nota_reg(DATA_WIDTH-10
downto 1);
when "01011" =>
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "01100" =>
tempo_nota_next <= tempo_nota_reg;
when "01101" =>
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "01110" =>
tempo_nota_next <= "0" & tempo_nota_reg(DATA_WIDTH-10
downto 1);
when "01111" =>
tempo_nota_next <= "00" & tempo_nota_reg(DATA_WIDTH-10
downto 2);
when "10000" =>
tempo_nota_next <= tempo_nota_reg;
when others =>
end case;
when novo_tempo2 =>
estado <= "1000";
state_next <= novo_tempo3;
tempo_notam_next <= to_integer(tempo_nota_reg);
when novo_tempo3 =>
estado <= "1000";
state_next <= conta_nota;
case tempo_reg is
when "00000" =>
tempo_notam_next <= tempo_notam_reg;
when "00001" =>
tempo_notam_next <= tempo_notam_reg * 7;
when "00010" =>
tempo_notam_next <= tempo_notam_reg * 3;
when "00011" =>
tempo_notam_next <= tempo_notam_reg * 5;
when "00100" =>
tempo_notam_next <= tempo_notam_reg;
when "00101" =>
tempo_notam_next <= tempo_notam_reg * 7;
when "00110" =>
tempo_notam_next <= tempo_notam_reg * 3;
when "00111" =>
tempo_notam_next <= tempo_notam_reg * 5;
when "01000" =>
tempo_notam_next <= tempo_notam_reg;
when "01001" =>
tempo_notam_next <= tempo_notam_reg * 5;
when "01010" =>
tempo_notam_next <= tempo_notam_reg * 3;
when "01011" =>
tempo_notam_next <= tempo_notam_reg * 7;
when "01100" =>
tempo_notam_next <= tempo_notam_reg * 2;
102
when "01101" =>
tempo_notam_next <= tempo_notam_reg * 9;
when "01110" =>
tempo_notam_next <= tempo_notam_reg * 5;
when "01111" =>
tempo_notam_next <= tempo_notam_reg * 11;
when "10000" =>
tempo_notam_next <= tempo_notam_reg * 3;
when others =>
end case;
when conta_nota =>
estado <= "1000";
if conta_notam_reg=tempo_notam_reg then
state_next <= lendo;
conta_notam_next <= 0;
case slot_leitura_reg is
when "00" =>
if laddr1_reg="0000000000" then
state_next <= escolha;
mem_tecla_next <= (others=>’1’);
else
laddr1_next <= laddr1_reg - 1;
end if;
when "01" =>
if laddr2_reg="0000000000" then
state_next <= escolha;
mem_tecla_next <= (others=>’1’);
else
laddr2_next <= laddr2_reg - 1;
end if;
when "10" =>
if laddr3_reg="0000000000" then
state_next <= escolha;
mem_tecla_next <= (others=>’1’);
else
laddr3_next <= laddr3_reg - 1;
end if;
when "11" =>
when others =>
end case;
else
if tick_10k='1' then
conta_notam_next <= conta_notam_reg + 1;
end if;
end if;
if tecla_next="01110110" then
state_next <= vai_escolha;
end if;
when vai_escolha =>
conta_nota_next <= (others=>'0');
conta_notam_next <= 0;
done_tick_next <= (others=>'0');
mem_tecla_next <= (others=>’1’);
if (tecla_next="01110110" and tecla_reg="11110000") then
state_next <= escolha;
end if;
when reseta_memoria =>
estado <= "1001";
addr1_next <= (others=>'0');
addr2_next <= (others=>'0');
103
addr3_next <= (others=>'0');
if contrst_reg=9999 then
state_next <= escolha;
contrst_next <= 0;
else
if tick_10k='1' then
contrst_next <= contrst_reg + 1;
end if;
end if;
end case;
end process;
--Lógica do valor das saídas para os módulos de processamento das notas e modulação
process(state_reg,ps2_in,ps2_done_tick,mem_tecla_reg,mem_done_tick,modulacao_reg)
begin
tecla_out <= (others=>'1');
data_done_tick <= '0';
processamento_enable <= '0';
modulacao <= (others=>'1');
modulacao_enable <= '0';
reseta_processamento <= '0';
case state_reg is
when escolha =>
reseta_processamento <= '1';
when livre =>
tecla_out <= ps2_in;
data_done_tick <= ps2_done_tick;
processamento_enable <= '1';
when gravando =>
tecla_out <= ps2_in;
data_done_tick <= ps2_done_tick;
processamento_enable <= '1';
when write_memoria =>
tecla_out <= ps2_in;
data_done_tick <= ps2_done_tick;
processamento_enable <= '1';
when lendo =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
when read_memoria =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
when novo_tempo1 =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
when novo_tempo2 =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
104
when novo_tempo3 =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
when conta_nota =>
tecla_out <= mem_tecla_reg;
data_done_tick <= mem_done_tick;
processamento_enable <= '1';
modulacao_enable <= '1';
modulacao <= modulacao_reg;
when others =>
end case;
end process;
--===================
--Controle do display
--===================
--Imagens do display
with state_reg select
in0 (7 downto 0) <=
"10001110" when escolha,
"10001110" when livre,
"10001110" when posicao_gravando,
"10001110" when gravando,
"10001110" when posicao_lendo,
"10001110" when modulacao_lendo,
"10001110" when tempo_lendo,
"10001110" when conta_nota,
"10001110" when memoria_cheia,
"10001110" when reseta_memoria,
"11111111" when others;
with state_reg select
in1 (7 downto 0) <=
"11000000" when escolha,
"11111001" when livre,
"10100100" when posicao_gravando,
"10100100" when gravando,
"10110000" when posicao_lendo,
"10110000" when modulacao_lendo,
"10110000" when tempo_lendo,
"10110000" when conta_nota,
"11000001" when memoria_cheia,
"10011001" when reseta_memoria,
"11111111" when others;
with state_reg select
in2 (7 downto 0) <=
"11111111" when escolha,
"11111111" when livre,
"10111111" when posicao_gravando,
"11111111" when gravando,
"10111111" when posicao_lendo,
"10111111" when modulacao_lendo,
"10111111" when tempo_lendo,
"11111111" when conta_nota,
"11000111" when memoria_cheia,
"11111111" when reseta_memoria,
"11111111" when others;
105
with state_reg select
in3 (7 downto 0) <=
"11111111" when escolha,
"11111111" when livre,
"11111001" when posicao_gravando,
"11111111" when gravando,
"11111001" when posicao_lendo,
"10100100" when modulacao_lendo,
"10110000" when tempo_lendo,
"11111111" when conta_nota,
"11000111" when memoria_cheia,
"11111111" when reseta_memoria,
"11111111" when others;
--Atualização do registrador de contagem
process(rst,clk)
begin
if rst='1' then
q_reg <= (others=>'0');
elsif (clk'event and clk='1') then
q_reg <= q_next;
end if;
end process;
--Lógica do próximo valor do registrador de contagem e saídas
q_next <= q_reg + 1;
sel <= std_logic_vector(q_reg(N-1 downto N-2));
process(sel,in0,in1,in2,in3)
begin
case sel is
when "00" =>
an <= "0111";
sseg <= in0;
when "01" =>
an <= "1011";
sseg <= in1;
when "10" =>
an <= "1101";
sseg <= in2;
when "11" =>
an <= "1110";
sseg <= in3;
when others =>
an <= "1111";
sseg <= (others=>'1');
end case;
end process;
end modo_operacao;
106
Anexo C – Código em VHDL do módulo de memória
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Memoria is
Generic ( ADDR_WIDTH : INTEGER;
DATA_WIDTH : INTEGER);
Port ( clk : in STD_LOGIC;
enable : in STD_LOGIC;
we : in STD_LOGIC;
addr : in STD_LOGIC_VECTOR (ADDR_WIDTH-1 downto 0);
din : in STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0);
dout : out STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0));
end Memoria;
architecture memoria of Memoria is
type ram_type is array (2**ADDR_WIDTH-1 downto 0) of std_logic_vector (DATA_WIDTH-1 downto
0);
signal ram : ram_type;
signal addr_reg : std_logic_vector (ADDR_WIDTH-1 downto 0);
begin
process(clk)
begin
if (clk'event and clk='1') then
if enable='1' then
if we='1' then
ram(to_integer(unsigned(addr))) <= din;
end if;
addr_reg <= addr;
end if;
end if;
end process;
dout <= ram(to_integer(unsigned(addr_reg)));
end memoria;
107
Anexo D – Código em VHDL do módulo de processamento das notas
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Processamento_notas is
Port ( data_in : in STD_LOGIC_VECTOR (7 downto 0);
ps2_done_tick : in STD_LOGIC;
processamento_enable, reseta_processamento : in STD_LOGIC;
clk : in STD_LOGIC;
rst : in STD_LOGIC;
freq1 : out STD_LOGIC_VECTOR (5 downto 0);
freq2 : out STD_LOGIC_VECTOR (5 downto 0);
freq3 : out STD_LOGIC_VECTOR (5 downto 0);
freq4 : out STD_LOGIC_VECTOR (5 downto 0);
freq5 : out STD_LOGIC_VECTOR (5 downto 0));
end Processamento_notas;
architecture processamento_notas of Processamento_notas is
type state_type is
(idle,break_idle,saida1,break_saida1,saida2,break_saida2,saida3,break_saida3,saida4,break_saida4,saida5,reset_
data,change_data,reset);
signal state_reg, state_next : state_type;
signal data_reg, data_next : std_logic_vector (7 downto 0);
signal dataprox_reg, dataprox_next : std_logic_vector (7 downto 0);
signal flag_reg, flag_next : std_logic_vector (4 downto 0);
signal data1_reg, data1_next, data2_reg, data2_next, data3_reg, data3_next, data4_reg, data4_next,
data5_reg, data5_next : std_logic_vector (7 downto 0);
signal nota1, nota2, nota3, nota4, nota5 : std_logic_vector (5 downto 0);
begin
--Atualização dos registradores de dados e estados
process(clk,rst)
begin
if rst='1' then
state_reg <= idle;
data_reg <= (others=>'1');
dataprox_reg <= (others=>'1');
flag_reg <= (others=>'0');
data1_reg <= (others=>'1');
data2_reg <= (others=>'1');
data3_reg <= (others=>'1');
data4_reg <= (others=>'1');
data5_reg <= (others=>'1');
elsif (clk'event and clk='1') then
state_reg <= state_next;
data_reg <= data_next;
dataprox_reg <= dataprox_next;
flag_reg <= flag_next;
data1_reg <= data1_next;
data2_reg <= data2_next;
data3_reg <= data3_next;
data4_reg <= data4_next;
data5_reg <= data5_next;
end if;
end process;
--Lógica do próximo valor do registrador data_reg
process(reseta_processamento,data_in,processamento_enable,state_reg,data_reg,dataprox_reg)
begin
108
data_next <= data_reg;
if state_reg=reset then
data_next <= (others=>'1');
elsif state_reg/=reset_data and state_reg/=change_data and processamento_enable='1' and
(data_in="11110000" or data_in="00010101" or data_in="00011101" or data_in="00100100" or
data_in="00101101" or data_in="00101100" or data_in="00110101" or data_in="00111100" or
data_in="01000011" or data_in="01000100" or data_in="01001101" or data_in="01010100" or
data_in="01011011" or data_in="00011100" or data_in="00011011" or data_in="00100011" or
data_in="00101011" or data_in="00110100" or data_in="00110011" or data_in="00111011" or
data_in="01000010" or data_in="01001011" or data_in="01001100" or data_in="01010010" or
data_in="01011101" or data_in="01100001" or data_in="00011010" or data_in="00100010" or
data_in="00100001" or data_in="00101010" or data_in="00110010" or data_in="00110001" or
data_in="00111010" or data_in="01000001" or data_in="01001001" or data_in="01001010" or
data_in="01010001" or data_in="01011001") then
data_next <= data_in;
elsif state_reg=reset_data then
data_next <= (others=>'1');
elsif state_reg=change_data then
data_next <= dataprox_reg;
end if;
end process;
--Lógica do próximo valor dos registradores de estado, registradores de dados e saídas
process(reseta_processamento,state_reg,data_reg,data_next,dataprox_reg,flag_reg,data1_reg,data2_reg,da
ta3_reg,data4_reg,data5_reg,nota1,nota2,nota3,nota4,nota5,ps2_done_tick)
begin
state_next <= state_reg;
dataprox_next <= dataprox_reg;
flag_next <= flag_reg;
data1_next <= data1_reg;
data2_next <= data2_reg;
data3_next <= data3_reg;
data4_next <= data4_reg;
data5_next <= data5_reg;
freq1 <= (others=>'1');
freq2 <= (others=>'1');
freq3 <= (others=>'1');
freq4 <= (others=>'1');
freq5 <= (others=>'1');
case state_reg is
when reset =>
state_next <= idle;
flag_next <= (others=>'0');
data1_next <= (others=>'1');
data2_next <= (others=>'1');
data3_next <= (others=>'1');
data4_next <= (others=>'1');
data5_next <= (others=>'1');
dataprox_next <= (others=>'1');
when idle =>
if data_next/=data_reg and data_next/="11110000" then
state_next <= saida1;
flag_next(0) <= '1';
data1_next <= data_next;
end if;
when saida1 =>
freq1 <= nota1;
if data_next/=data_reg and data_next/="11110000" then
if data_next=data1_reg and data_reg="11110000" then
state_next <= break_idle;
109
else
state_next <= saida2;
flag_next(1) <= '1';
data2_next <= data_next;
end if;
end if;
when break_idle =>
freq1 <= nota1;
state_next <= reset_data;
flag_next(0) <= '0';
data1_next <= (others=>'1');
when saida2 =>
freq1 <= nota1;
freq2 <= nota2;
if data_next/=data_reg and data_next/="11110000" then
if (data_next=data1_reg or data_next=data2_reg) and data_reg="11110000"
then
state_next <= break_saida1;
else
state_next <= saida3;
flag_next(2) <= '1';
data3_next <= data_next;
end if;
end if;
when break_saida1 =>
freq1 <= nota1;
freq2 <= nota2;
flag_next(1) <= '0';
if data_reg=data1_reg then
state_next <= change_data;
dataprox_next <= data2_reg;
data2_next <= (others=>'1');
data1_next <= data2_reg;
elsif data_reg=data2_reg then
state_next <= reset_data;
data2_next <= (others=>'1');
end if;
when saida3 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
if data_next/=data_reg and data_next/="11110000" then
if (data_next=data1_reg or data_next=data2_reg or data_next=data3_reg) and
data_reg="11110000" then
state_next <= break_saida2;
else
state_next <= saida4;
flag_next(3) <= '1';
data4_next <= data_next;
end if;
end if;
when break_saida2 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
flag_next(2) <= '0';
if data_reg=data1_reg then
state_next <= change_data;
dataprox_next <= data3_reg;
data3_next <= (others=>'1');
110
data2_next <= data3_reg;
data1_next <= data2_reg;
elsif data_reg=data2_reg then
state_next <= change_data;
dataprox_next <= data3_reg;
data3_next <= (others=>'1');
data2_next <= data3_reg;
elsif data_reg=data3_reg then
state_next <= reset_data;
data3_next <= (others=>'1');
end if;
when saida4 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
if data_next/=data_reg and data_next/="11110000" then
if (data_next=data1_reg or data_next=data2_reg or data_next=data3_reg or
data_next=data4_reg) and data_reg="11110000" then
state_next <= break_saida3;
else
state_next <= saida5;
flag_next(4) <= '1';
data5_next <= data_next;
end if;
end if;
when break_saida3 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
flag_next(3) <= '0';
if data_reg=data1_reg then
state_next <= change_data;
dataprox_next <= data4_reg;
data4_next <= (others=>'1');
data3_next <= data4_reg;
data2_next <= data3_reg;
data1_next <= data2_reg;
elsif data_reg=data2_reg then
state_next <= change_data;
dataprox_next <= data4_reg;
data4_next <= (others=>'1');
data3_next <= data4_reg;
data2_next <= data3_reg;
elsif data_reg=data3_reg then
state_next <= change_data;
dataprox_next <= data4_reg;
data4_next <= (others=>'1');
data3_next <= data4_reg;
elsif data_reg=data4_reg then
state_next <= reset_data;
data4_next <= (others=>'1');
end if;
when saida5 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
freq5 <= nota5;
111
if (data_next=data1_reg or data_next=data2_reg or data_next=data3_reg or
data_next=data4_reg or data_next=data5_reg) and data_reg="11110000" then
state_next <= break_saida4;
end if;
when break_saida4 =>
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
freq5 <= nota5;
flag_next(4) <= '0';
if data_reg=data1_reg then
state_next <= change_data;
dataprox_next <= data5_reg;
data5_next <= (others=>'1');
data4_next <= data5_reg;
data3_next <= data4_reg;
data2_next <= data3_reg;
data1_next <= data2_reg;
elsif data_reg=data2_reg then
state_next <= change_data;
dataprox_next <= data5_reg;
data5_next <= (others=>'1');
data4_next <= data5_reg;
data3_next <= data4_reg;
data2_next <= data3_reg;
elsif data_reg=data3_reg then
state_next <= change_data;
dataprox_next <= data5_reg;
data5_next <= (others=>'1');
data4_next <= data5_reg;
data3_next <= data4_reg;
elsif data_reg=data4_reg then
state_next <= change_data;
dataprox_next <= data5_reg;
data5_next <= (others=>'1');
data4_next <= data5_reg;
elsif data_reg=data5_reg then
state_next <= reset_data;
data5_next <= (others=>'1');
end if;
when reset_data =>
if flag_reg="01111" then
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
if ps2_done_tick='1' then
state_next <= saida4;
end if;
elsif flag_reg="00111" then
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
if ps2_done_tick='1' then
state_next <= saida3;
end if;
elsif flag_reg="00011" then
freq1 <= nota1;
freq2 <= nota2;
112
if ps2_done_tick='1' then
state_next <= saida2;
end if;
elsif flag_reg="00001" then
freq1 <= nota1;
if ps2_done_tick='1' then
state_next <= saida1;
end if;
elsif flag_reg="00000" then
if ps2_done_tick='1' then
state_next <= idle;
end if;
end if;
when change_data =>
if flag_reg="01111" then
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
freq4 <= nota4;
if ps2_done_tick='1' then
state_next <= saida4;
end if;
elsif flag_reg="00111" then
freq1 <= nota1;
freq2 <= nota2;
freq3 <= nota3;
if ps2_done_tick='1' then
state_next <= saida3;
end if;
elsif flag_reg="00011" then
freq1 <= nota1;
freq2 <= nota2;
if ps2_done_tick='1' then
state_next <= saida2;
end if;
elsif flag_reg="00001" then
freq1 <= nota1;
if ps2_done_tick='1' then
state_next <= saida1;
end if;
elsif flag_reg="00000" then
if ps2_done_tick='1' then
state_next <= idle;
end if;
end if;
end case;
if reseta_processamento='1' then
state_next <= reset;
end if;
end process;
--Lógica do valor dos sinais nota(1-5)
with data1_reg select
nota1 <= "001100" when "00010101",
"001101" when "00011101",
"001110" when "00100100",
"001111" when "00101101",
"010000" when "00101100",
"010001" when "00110101",
"010010" when "00111100",
113
"010011" when "01000011",
"010100" when "01000100",
"010101" when "01001101",
"010110" when "01010100",
"010111" when "01011011",
"011000" when "00011100",
"011001" when "00011011",
"011010" when "00100011",
"011011" when "00101011",
"011100" when "00110100",
"011101" when "00110011",
"011110" when "00111011",
"011111" when "01000010",
"100000" when "01001011",
"100001" when "01001100",
"100010" when "01010010",
"100011" when "01011101",
"100100" when "01100001",
"100101" when "00011010",
"100110" when "00100010",
"100111" when "00100001",
"101000" when "00101010",
"101001" when "00110010",
"101010" when "00110001",
"101011" when "00111010",
"101100" when "01000001",
"101101" when "01001001",
"101110" when "01001010",
"101111" when "01010001",
"111111" when others;
with data2_reg select
nota2 <= "001100" when "00010101",
"001101" when "00011101",
"001110" when "00100100",
"001111" when "00101101",
"010000" when "00101100",
"010001" when "00110101",
"010010" when "00111100",
"010011" when "01000011",
"010100" when "01000100",
"010101" when "01001101",
"010110" when "01010100",
"010111" when "01011011",
"011000" when "00011100",
"011001" when "00011011",
"011010" when "00100011",
"011011" when "00101011",
"011100" when "00110100",
"011101" when "00110011",
"011110" when "00111011",
"011111" when "01000010",
"100000" when "01001011",
"100001" when "01001100",
"100010" when "01010010",
"100011" when "01011101",
"100100" when "01100001",
"100101" when "00011010",
"100110" when "00100010",
"100111" when "00100001",
114
"101000" when "00101010",
"101001" when "00110010",
"101010" when "00110001",
"101011" when "00111010",
"101100" when "01000001",
"101101" when "01001001",
"101110" when "01001010",
"101111" when "01010001",
"111111" when others;
with data3_reg select
nota3 <= "001100" when "00010101",
"001101" when "00011101",
"001110" when "00100100",
"001111" when "00101101",
"010000" when "00101100",
"010001" when "00110101",
"010010" when "00111100",
"010011" when "01000011",
"010100" when "01000100",
"010101" when "01001101",
"010110" when "01010100",
"010111" when "01011011",
"011000" when "00011100",
"011001" when "00011011",
"011010" when "00100011",
"011011" when "00101011",
"011100" when "00110100",
"011101" when "00110011",
"011110" when "00111011",
"011111" when "01000010",
"100000" when "01001011",
"100001" when "01001100",
"100010" when "01010010",
"100011" when "01011101",
"100100" when "01100001",
"100101" when "00011010",
"100110" when "00100010",
"100111" when "00100001",
"101000" when "00101010",
"101001" when "00110010",
"101010" when "00110001",
"101011" when "00111010",
"101100" when "01000001",
"101101" when "01001001",
"101110" when "01001010",
"101111" when "01010001",
"111111" when others;
with data4_reg select
nota4 <= "001100" when "00010101",
"001101" when "00011101",
"001110" when "00100100",
"001111" when "00101101",
"010000" when "00101100",
"010001" when "00110101",
"010010" when "00111100",
"010011" when "01000011",
"010100" when "01000100",
"010101" when "01001101",
115
"010110" when "01010100",
"010111" when "01011011",
"011000" when "00011100",
"011001" when "00011011",
"011010" when "00100011",
"011011" when "00101011",
"011100" when "00110100",
"011101" when "00110011",
"011110" when "00111011",
"011111" when "01000010",
"100000" when "01001011",
"100001" when "01001100",
"100010" when "01010010",
"100011" when "01011101",
"100100" when "01100001",
"100101" when "00011010",
"100110" when "00100010",
"100111" when "00100001",
"101000" when "00101010",
"101001" when "00110010",
"101010" when "00110001",
"101011" when "00111010",
"101100" when "01000001",
"101101" when "01001001",
"101110" when "01001010",
"101111" when "01010001",
"111111" when others;
with data5_reg select
nota5 <= "001100" when "00010101",
"001101" when "00011101",
"001110" when "00100100",
"001111" when "00101101",
"010000" when "00101100",
"010001" when "00110101",
"010010" when "00111100",
"010011" when "01000011",
"010100" when "01000100",
"010101" when "01001101",
"010110" when "01010100",
"010111" when "01011011",
"011000" when "00011100",
"011001" when "00011011",
"011010" when "00100011",
"011011" when "00101011",
"011100" when "00110100",
"011101" when "00110011",
"011110" when "00111011",
"011111" when "01000010",
"100000" when "01001011",
"100001" when "01001100",
"100010" when "01010010",
"100011" when "01011101",
"100100" when "01100001",
"100101" when "00011010",
"100110" when "00100010",
"100111" when "00100001",
"101000" when "00101010",
"101001" when "00110010",
"101010" when "00110001",
116
"101011" when "00111010",
"101100" when "01000001",
"101101" when "01001001",
"101110" when "01001010",
"101111" when "01010001",
"111111" when others;
end processamento_notas;
117
Anexo E – Código em VHDL do módulo de modulação
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Modulacao is
Port ( modulacao_enable : in STD_LOGIC;
modulacao : in STD_LOGIC_VECTOR (4 downto 0);
freq1 : in STD_LOGIC_VECTOR (5 downto 0);
freq2 : in STD_LOGIC_VECTOR (5 downto 0);
freq3 : in STD_LOGIC_VECTOR (5 downto 0);
freq4 : in STD_LOGIC_VECTOR (5 downto 0);
freq5 : in STD_LOGIC_VECTOR (5 downto 0);
freq_mod1 : out STD_LOGIC_VECTOR (5 downto 0);
freq_mod2 : out STD_LOGIC_VECTOR (5 downto 0);
freq_mod3 : out STD_LOGIC_VECTOR (5 downto 0);
freq_mod4 : out STD_LOGIC_VECTOR (5 downto 0);
freq_mod5 : out STD_LOGIC_VECTOR (5 downto 0));
end Modulacao;
architecture modulacao of Modulacao is
signal nota1, nota2, nota3, nota4, nota5 : unsigned (5 downto 0);
begin
--Lógica da saida
process(modulacao_enable,modulacao,nota1,nota2,nota3,nota4,nota5,freq1,freq2,freq3,freq4,freq5)
begin
nota1 <= unsigned(freq1);
nota2 <= unsigned(freq2);
nota3 <= unsigned(freq3);
nota4 <= unsigned(freq4);
nota5 <= unsigned(freq5);
freq_mod1 <= (others=>'1');
freq_mod2 <= (others=>'1');
freq_mod3 <= (others=>'1');
freq_mod4 <= (others=>'1');
freq_mod5 <= (others=>'1');
if modulacao_enable='1' then
if nota1/="111111" then
case modulacao is
when "00000" =>
freq_mod1 <= std_logic_vector(nota1);
when "00001" =>
freq_mod1 <= std_logic_vector(nota1 + 1);
when "00010" =>
freq_mod1 <= std_logic_vector(nota1 + 2);
when "00011" =>
freq_mod1 <= std_logic_vector(nota1 + 3);
when "00100" =>
freq_mod1 <= std_logic_vector(nota1 + 4);
when "00101" =>
freq_mod1 <= std_logic_vector(nota1 + 5);
when "00110" =>
freq_mod1 <= std_logic_vector(nota1 + 6);
when "00111" =>
freq_mod1 <= std_logic_vector(nota1 + 7);
when "01000" =>
freq_mod1 <= std_logic_vector(nota1 + 8);
when "01001" =>
118
freq_mod1 <= std_logic_vector(nota1 + 9);
when "01010" =>
freq_mod1 <= std_logic_vector(nota1 + 10);
when "01011" =>
freq_mod1 <= std_logic_vector(nota1 + 11);
when "01100" =>
freq_mod1 <= std_logic_vector(nota1 + 12);
when "01101" =>
freq_mod1 <= std_logic_vector(nota1 - 1);
when "01110" =>
freq_mod1 <= std_logic_vector(nota1 - 2);
when "01111" =>
freq_mod1 <= std_logic_vector(nota1 - 3);
when "10000" =>
freq_mod1 <= std_logic_vector(nota1 - 4);
when "10001" =>
freq_mod1 <= std_logic_vector(nota1 - 5);
when "10010" =>
freq_mod1 <= std_logic_vector(nota1 - 6);
when "10011" =>
freq_mod1 <= std_logic_vector(nota1 - 7);
when "10100" =>
freq_mod1 <= std_logic_vector(nota1 - 8);
when "10101" =>
freq_mod1 <= std_logic_vector(nota1 - 9);
when "10110" =>
freq_mod1 <= std_logic_vector(nota1 - 10);
when "10111" =>
freq_mod1 <= std_logic_vector(nota1 - 11);
when "11000" =>
freq_mod1 <= std_logic_vector(nota1 - 12);
when others =>
freq_mod1 <= std_logic_vector(nota1);
end case;
end if;
if nota2/="111111" then
case modulacao is
when "00000" =>
freq_mod2 <= std_logic_vector(nota2);
when "00001" =>
freq_mod2 <= std_logic_vector(nota2 + 1);
when "00010" =>
freq_mod2 <= std_logic_vector(nota2 + 2);
when "00011" =>
freq_mod2 <= std_logic_vector(nota2 + 3);
when "00100" =>
freq_mod2 <= std_logic_vector(nota2 + 4);
when "00101" =>
freq_mod2 <= std_logic_vector(nota2 + 5);
when "00110" =>
freq_mod2 <= std_logic_vector(nota2 + 6);
when "00111" =>
freq_mod2 <= std_logic_vector(nota2 + 7);
when "01000" =>
freq_mod2 <= std_logic_vector(nota2 + 8);
when "01001" =>
freq_mod2 <= std_logic_vector(nota2 + 9);
when "01010" =>
freq_mod2 <= std_logic_vector(nota2 + 10);
when "01011" =>
119
freq_mod2 <= std_logic_vector(nota2 + 11);
when "01100" =>
freq_mod2 <= std_logic_vector(nota2 + 12);
when "01101" =>
freq_mod2 <= std_logic_vector(nota2 - 1);
when "01110" =>
freq_mod2 <= std_logic_vector(nota2 - 2);
when "01111" =>
freq_mod2 <= std_logic_vector(nota2 - 3);
when "10000" =>
freq_mod2 <= std_logic_vector(nota2 - 4);
when "10001" =>
freq_mod2 <= std_logic_vector(nota2 - 5);
when "10010" =>
freq_mod2 <= std_logic_vector(nota2 - 6);
when "10011" =>
freq_mod2 <= std_logic_vector(nota2 - 7);
when "10100" =>
freq_mod2 <= std_logic_vector(nota2 - 8);
when "10101" =>
freq_mod2 <= std_logic_vector(nota2 - 9);
when "10110" =>
freq_mod2 <= std_logic_vector(nota2 - 10);
when "10111" =>
freq_mod2 <= std_logic_vector(nota2 - 11);
when "11000" =>
freq_mod2 <= std_logic_vector(nota2 - 12);
when others =>
freq_mod2 <= std_logic_vector(nota2);
end case;
end if;
if nota3/="111111" then
case modulacao is
when "00000" =>
freq_mod3 <= std_logic_vector(nota3);
when "00001" =>
freq_mod3 <= std_logic_vector(nota3 + 1);
when "00010" =>
freq_mod3 <= std_logic_vector(nota3 + 2);
when "00011" =>
freq_mod3 <= std_logic_vector(nota3 + 3);
when "00100" =>
freq_mod3 <= std_logic_vector(nota3 + 4);
when "00101" =>
freq_mod3 <= std_logic_vector(nota3 + 5);
when "00110" =>
freq_mod3 <= std_logic_vector(nota3 + 6);
when "00111" =>
freq_mod3 <= std_logic_vector(nota3 + 7);
when "01000" =>
freq_mod3 <= std_logic_vector(nota3 + 8);
when "01001" =>
freq_mod3 <= std_logic_vector(nota3 + 9);
when "01010" =>
freq_mod3 <= std_logic_vector(nota3 + 10);
when "01011" =>
freq_mod3 <= std_logic_vector(nota3 + 11);
when "01100" =>
freq_mod3 <= std_logic_vector(nota3 + 12);
when "01101" =>
120
freq_mod3 <= std_logic_vector(nota3 - 1);
when "01110" =>
freq_mod3 <= std_logic_vector(nota3 - 2);
when "01111" =>
freq_mod3 <= std_logic_vector(nota3 - 3);
when "10000" =>
freq_mod3 <= std_logic_vector(nota3 - 4);
when "10001" =>
freq_mod3 <= std_logic_vector(nota3 - 5);
when "10010" =>
freq_mod3 <= std_logic_vector(nota3 - 6);
when "10011" =>
freq_mod3 <= std_logic_vector(nota3 - 7);
when "10100" =>
freq_mod3 <= std_logic_vector(nota3 - 8);
when "10101" =>
freq_mod3 <= std_logic_vector(nota3 - 9);
when "10110" =>
freq_mod3 <= std_logic_vector(nota3 - 10);
when "10111" =>
freq_mod3 <= std_logic_vector(nota3 - 11);
when "11000" =>
freq_mod3 <= std_logic_vector(nota3 - 12);
when others =>
freq_mod3 <= std_logic_vector(nota3);
end case;
end if;
if nota4/="111111" then
case modulacao is
when "00000" =>
freq_mod4 <= std_logic_vector(nota4);
when "00001" =>
freq_mod4 <= std_logic_vector(nota4 + 1);
when "00010" =>
freq_mod4 <= std_logic_vector(nota4 + 2);
when "00011" =>
freq_mod4 <= std_logic_vector(nota4 + 3);
when "00100" =>
freq_mod4 <= std_logic_vector(nota4 + 4);
when "00101" =>
freq_mod4 <= std_logic_vector(nota4 + 5);
when "00110" =>
freq_mod4 <= std_logic_vector(nota4 + 6);
when "00111" =>
freq_mod4 <= std_logic_vector(nota4 + 7);
when "01000" =>
freq_mod4 <= std_logic_vector(nota4 + 8);
when "01001" =>
freq_mod4 <= std_logic_vector(nota4 + 9);
when "01010" =>
freq_mod4 <= std_logic_vector(nota4 + 10);
when "01011" =>
freq_mod4 <= std_logic_vector(nota4 + 11);
when "01100" =>
freq_mod4 <= std_logic_vector(nota4 + 12);
when "01101" =>
freq_mod4 <= std_logic_vector(nota4 - 1);
when "01110" =>
freq_mod4 <= std_logic_vector(nota4 - 2);
when "01111" =>
121
freq_mod4 <= std_logic_vector(nota4 - 3);
when "10000" =>
freq_mod4 <= std_logic_vector(nota4 - 4);
when "10001" =>
freq_mod4 <= std_logic_vector(nota4 - 5);
when "10010" =>
freq_mod4 <= std_logic_vector(nota4 - 6);
when "10011" =>
freq_mod4 <= std_logic_vector(nota4 - 7);
when "10100" =>
freq_mod4 <= std_logic_vector(nota4 - 8);
when "10101" =>
freq_mod4 <= std_logic_vector(nota4 - 9);
when "10110" =>
freq_mod4 <= std_logic_vector(nota4 - 10);
when "10111" =>
freq_mod4 <= std_logic_vector(nota4 - 11);
when "11000" =>
freq_mod4 <= std_logic_vector(nota4 - 12);
when others =>
freq_mod4 <= std_logic_vector(nota4);
end case;
end if;
if nota5/="111111" then
case modulacao is
when "00000" =>
freq_mod5 <= std_logic_vector(nota5);
when "00001" =>
freq_mod5 <= std_logic_vector(nota5 + 1);
when "00010" =>
freq_mod5 <= std_logic_vector(nota5 + 2);
when "00011" =>
freq_mod5 <= std_logic_vector(nota5 + 3);
when "00100" =>
freq_mod5 <= std_logic_vector(nota5 + 4);
when "00101" =>
freq_mod5 <= std_logic_vector(nota5 + 5);
when "00110" =>
freq_mod5 <= std_logic_vector(nota5 + 6);
when "00111" =>
freq_mod5 <= std_logic_vector(nota5 + 7);
when "01000" =>
freq_mod5 <= std_logic_vector(nota5 + 8);
when "01001" =>
freq_mod5 <= std_logic_vector(nota5 + 9);
when "01010" =>
freq_mod5 <= std_logic_vector(nota5 + 10);
when "01011" =>
freq_mod5 <= std_logic_vector(nota5 + 11);
when "01100" =>
freq_mod5 <= std_logic_vector(nota5 + 12);
when "01101" =>
freq_mod5 <= std_logic_vector(nota5 - 1);
when "01110" =>
freq_mod5 <= std_logic_vector(nota5 - 2);
when "01111" =>
freq_mod5 <= std_logic_vector(nota5 - 3);
when "10000" =>
freq_mod5 <= std_logic_vector(nota5 - 4);
when "10001" =>
122
freq_mod5 <= std_logic_vector(nota5 - 5);
when "10010" =>
freq_mod5 <= std_logic_vector(nota5 - 6);
when "10011" =>
freq_mod5 <= std_logic_vector(nota5 - 7);
when "10100" =>
freq_mod5 <= std_logic_vector(nota5 - 8);
when "10101" =>
freq_mod5 <= std_logic_vector(nota5 - 9);
when "10110" =>
freq_mod5 <= std_logic_vector(nota5 - 10);
when "10111" =>
freq_mod5 <= std_logic_vector(nota5 - 11);
when "11000" =>
freq_mod5 <= std_logic_vector(nota5 - 12);
when others =>
freq_mod5 <= std_logic_vector(nota5);
end case;
end if;
else
freq_mod1 <= std_logic_vector(nota1);
freq_mod2 <= std_logic_vector(nota2);
freq_mod3 <= std_logic_vector(nota3);
freq_mod4 <= std_logic_vector(nota4);
freq_mod5 <= std_logic_vector(nota5);
end if;
end process;
end modulacao;
123
Anexo F – Código em VHDL do módulo de geração de frequências
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Gerador_de_frequencias is
Port (clk, rst : in STD_LOGIC;
nota_in : in STD_LOGIC_VECTOR (5 downto 0);
freq_out : out STD_LOGIC);
end Gerador_de_frequencias;
architecture gerador_de_frequencias of Gerador_de_frequencias is
type state_type is
(idle,do1,dos1,re1,res1,mi1,fa1,fas1,sol1,sols1,la1,las1,si1,do2,dos2,re2,res2,mi2,fa2,fas2,sol2,sols2,la2,las2,si2,
do3,dos3,re3,res3,mi3,fa3,fas3,sol3,sols3,la3,las3,si3,do4,dos4,re4,res4,mi4,fa4,fas4,sol4,sols4,la4,las4,si4,do5,
dos5,re5,res5,mi5,fa5,fas5,sol5,sols5,la5,las5,si5);
signal state_next, state_reg : state_type;
signal freq_reg, freq_next : STD_LOGIC;
signal count_reg, count_next : integer range 0 to 764455;
begin
--Atualização dos registradores de estado e dados
process(clk,rst)
begin
if rst='1' then
state_reg <= idle;
count_reg <= 0;
freq_reg <= '0';
elsif (clk'event and clk='1') then
state_reg <= state_next;
count_reg <= count_next;
freq_reg <= freq_next;
end if;
end process;
--Lógica do próximo valor dos registradores de dados
process(nota_in,state_reg,count_reg,freq_reg)
begin
count_next <= count_reg;
freq_next <= freq_reg;
case state_reg is
when idle =>
freq_next <= '0';
when do1 =>
if nota_in="000000" then
if count_reg<382228 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<764455 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when dos1 =>
124
if nota_in="000001" then
if count_reg<360771 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<721541 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when re1 =>
if nota_in="000010" then
if count_reg<340525 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<681049 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when res1 =>
if nota_in="000011" then
if count_reg<321411 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<642821 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when mi1 =>
if nota_in="000100" then
if count_reg<303372 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<606743 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
125
freq_next <= '0';
count_next <= 0;
end if;
when fa1 =>
if nota_in="000101" then
if count_reg<286345 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<572690 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fas1 =>
if nota_in="000110" then
if count_reg<270273 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<540546 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sol1 =>
if nota_in="000111" then
if count_reg<255104 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<510208 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sols1 =>
if nota_in="001000" then
if count_reg<240778 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<481555 then
freq_next <= '1';
count_next <= count_reg+1;
else
126
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when la1 =>
if nota_in="001001" then
if count_reg<227272 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<454544 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when las1 =>
if nota_in="001010" then
if count_reg<214518 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<429036 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when si1 =>
if nota_in="001011" then
if count_reg<202478 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<404955 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when do2 =>
if nota_in="001100" then
if count_reg<191117 then
freq_next <= '0';
count_next <= count_reg+1;
127
elsif count_reg<382233 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when dos2 =>
if nota_in="001101" then
if count_reg<180388 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<360775 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when re2 =>
if nota_in="001110" then
if count_reg<170265 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<340529 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when res2 =>
if nota_in="001111" then
if count_reg<160709 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<321418 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when mi2 =>
128
if nota_in="010000" then
if count_reg<151690 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<303379 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fa2 =>
if nota_in="010001" then
if count_reg<143176 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<286351 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fas2 =>
if nota_in="010010" then
if count_reg<135135 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<270269 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sol2 =>
if nota_in="010011" then
if count_reg<127551 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<255102 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
129
freq_next <= '0';
count_next <= 0;
end if;
when sols2 =>
if nota_in="010100" then
if count_reg<120394 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<240788 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when la2 =>
if nota_in="010101" then
if count_reg<113636 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<227272 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when las2 =>
if nota_in="010110" then
if count_reg<107259 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<214518 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when si2 =>
if nota_in="010111" then
if count_reg<101239 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<202477 then
freq_next <= '1';
count_next <= count_reg+1;
else
130
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when do3 =>
if nota_in="011000" then
if count_reg<95555 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<191108 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when dos3 =>
if nota_in="011001" then
if count_reg<90194 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<180387 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when re3 =>
if nota_in="011010" then
if count_reg<85132 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<170263 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when res3 =>
if nota_in="011011" then
if count_reg<80352 then
freq_next <= '0';
count_next <= count_reg+1;
131
elsif count_reg<160703 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when mi3 =>
if nota_in="011100" then
if count_reg<75842 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<151684 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fa3 =>
if nota_in="011101" then
if count_reg<71586 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<143171 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fas3 =>
if nota_in="011110" then
if count_reg<67569 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<135137 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sol3 =>
132
if nota_in="011111" then
if count_reg<63775 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<127550 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sols3 =>
if nota_in="100000" then
if count_reg<60197 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<120393 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when la3 =>
if nota_in="100001" then
if count_reg<56818 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<113635 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when las3 =>
if nota_in="100010" then
if count_reg<53629 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<107258 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
133
freq_next <= '0';
count_next <= 0;
end if;
when si3 =>
if nota_in="100011" then
if count_reg<50620 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<101238 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when do4 =>
if nota_in="100100" then
if count_reg<47778 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<95555 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when dos4 =>
if nota_in="100101" then
if count_reg<45096 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<90191 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when re4 =>
if nota_in="100110" then
if count_reg<42565 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<85130 then
freq_next <= '1';
count_next <= count_reg+1;
else
134
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when res4 =>
if nota_in="100111" then
if count_reg<40177 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<80351 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when mi4 =>
if nota_in="101000" then
if count_reg<37921 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<75842 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fa4 =>
if nota_in="101001" then
if count_reg<35793 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<71585 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fas4 =>
if nota_in="101010" then
if count_reg<33784 then
freq_next <= '0';
count_next <= count_reg+1;
135
elsif count_reg<67568 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sol4 =>
if nota_in="101011" then
if count_reg<31888 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<63775 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sols4 =>
if nota_in="101100" then
if count_reg<30098 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<60196 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when la4 =>
if nota_in="101101" then
if count_reg<28409 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<56817 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when las4 =>
136
if nota_in="101110" then
if count_reg<26814 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<53628 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when si4 =>
if nota_in="101111" then
if count_reg<25309 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<50618 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when do5 =>
if nota_in="110000" then
if count_reg<23889 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<47777 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when dos5 =>
if nota_in="110001" then
if count_reg<22549 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<45097 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
137
freq_next <= '0';
count_next <= 0;
end if;
when re5 =>
if nota_in="110010" then
if count_reg<21282 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<42563 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when res5 =>
if nota_in="110011" then
if count_reg<20088 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<40176 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when mi5 =>
if nota_in="110100" then
if count_reg<18961 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<37921 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fa5 =>
if nota_in="110101" then
if count_reg<17897 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<35793 then
freq_next <= '1';
count_next <= count_reg+1;
else
138
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when fas5 =>
if nota_in="110110" then
if count_reg<16892 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<33783 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sol5 =>
if nota_in="110111" then
if count_reg<15944 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<31887 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when sols5 =>
if nota_in="111000" then
if count_reg<15049 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<30098 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when la5 =>
if nota_in="111001" then
if count_reg<14204 then
freq_next <= '0';
count_next <= count_reg+1;
139
elsif count_reg<28409 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when las5 =>
if nota_in="111010" then
if count_reg<13407 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<26814 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
when si5 =>
if nota_in="111011" then
if count_reg<12655 then
freq_next <= '0';
count_next <= count_reg+1;
elsif count_reg<25309 then
freq_next <= '1';
count_next <= count_reg+1;
else
freq_next <= '1';
count_next <= 0;
end if;
else
freq_next <= '0';
count_next <= 0;
end if;
end case;
end process;
--Lógica do próximo valor do registrador de estados
process(nota_in,state_reg)
begin
state_next <= state_reg;
case nota_in is
when "000000" =>
state_next <= do1;
when "000001" =>
state_next <= dos1;
when "000010" =>
state_next <= re1;
when "000011" =>
state_next <= res1;
when "000100" =>
140
state_next <= mi1;
when "000101" =>
state_next <= fa1;
when "000110" =>
state_next <= fas1;
when "000111" =>
state_next <= sol1;
when "001000" =>
state_next <= sols1;
when "001001" =>
state_next <= la1;
when "001010" =>
state_next <= las1;
when "001011" =>
state_next <= si1;
when "001100" =>
state_next <= do2;
when "001101" =>
state_next <= dos2;
when "001110" =>
state_next <= re2;
when "001111" =>
state_next <= res2;
when "010000" =>
state_next <= mi2;
when "010001" =>
state_next <= fa2;
when "010010" =>
state_next <= fas2;
when "010011" =>
state_next <= sol2;
when "010100" =>
state_next <= sols2;
when "010101" =>
state_next <= la2;
when "010110" =>
state_next <= las2;
when "010111" =>
state_next <= si2;
when "011000" =>
state_next <= do3;
when "011001" =>
state_next <= dos3;
when "011010" =>
state_next <= re3;
when "011011" =>
state_next <= res3;
when "011100" =>
state_next <= mi3;
when "011101" =>
state_next <= fa3;
when "011110" =>
state_next <= fas3;
when "011111" =>
state_next <= sol3;
when "100000" =>
state_next <= sols3;
when "100001" =>
state_next <= la3;
when "100010" =>
141
state_next <= las3;
when "100011" =>
state_next <= si3;
when "100100" =>
state_next <= do4;
when "100101" =>
state_next <= dos4;
when "100110" =>
state_next <= re4;
when "100111" =>
state_next <= res4;
when "101000" =>
state_next <= mi4;
when "101001" =>
state_next <= fa4;
when "101010" =>
state_next <= fas4;
when "101011" =>
state_next <= sol4;
when "101100" =>
state_next <= sols4;
when "101101" =>
state_next <= la4;
when "101110" =>
state_next <= las4;
when "101111" =>
state_next <= si4;
when "110000" =>
state_next <= do5;
when "110001" =>
state_next <= dos5;
when "110010" =>
state_next <= re5;
when "110011" =>
state_next <= res5;
when "110100" =>
state_next <= mi5;
when "110101" =>
state_next <= fa5;
when "110110" =>
state_next <= fas5;
when "110111" =>
state_next <= sol5;
when "111000" =>
state_next <= sols5;
when "111001" =>
state_next <= la5;
when "111010" =>
state_next <= las5;
when "111011" =>
state_next <= si5;
when others =>
state_next <= idle;
end case;
end process;
--Lógica da saída
freq_out <= freq_reg;
end gerador_de_frequencias;
142
Anexo G – Código em VHDL do módulo de controle VGA
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Controle_VGA is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
nota1_mod, nota2_mod, nota3_mod, nota4_mod, nota5_mod : in STD_LOGIC_VECTOR (5
downto 0);
estado : in STD_LOGIC_VECTOR (3 downto 0);
h_sync, v_sync : out STD_LOGIC;
rgb : out STD_LOGIC_VECTOR (7 downto 0));
end Controle_VGA;
architecture controle_VGA of Controle_VGA is
signal pixel_x, pixel_y : std_logic_vector (9 downto 0);
signal rgb_reg, rgb_next : std_logic_vector (7 downto 0);
signal video_on, pixel_tick : std_logic;
begin
sync_VGA_unit : entity work.Sync_VGA(sync_VGA)
port map (clk=>clk, rst=>rst, h_sync=>h_sync, v_sync=>v_sync,
video_on=>video_on, p_tick=>pixel_tick, pixel_x=>pixel_x,
pixel_y=>pixel_y);
pixelgen_VGA_unit : entity work.Pixelgen_VGA(pixelgen_VGA)
port map (clk=>clk, video_on=>video_on, pixel_x=>pixel_x, pixel_y=>pixel_y,
graph_rgb=>rgb_next, estado=>estado,
nota1_mod=>nota1_mod, nota2_mod=>nota2_mod,
nota3_mod=>nota3_mod, nota4_mod=>nota4_mod, nota5_mod=>nota5_mod);
process(clk,rst)
begin
if rst='1' then
rgb_reg <= (others=>'0');
elsif (clk'event and clk='1') then
if pixel_tick='1' then
rgb_reg <= rgb_next;
end if;
end if;
end process;
rgb <= rgb_reg;
end controle_VGA;
143
Anexo H – Código em VHDL do módulo de sincronização VGA
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Sync_VGA is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
h_sync : out STD_LOGIC;
v_sync : out STD_LOGIC;
video_on : out STD_LOGIC;
p_tick : out STD_LOGIC;
pixel_x : out STD_LOGIC_VECTOR (9 downto 0);
pixel_y : out STD_LOGIC_VECTOR (9 downto 0));
end Sync_VGA;
architecture sync_VGA of Sync_VGA is
constant HD : integer:=640;
constant HF : integer:=16;
constant HB : integer:=48;
constant HR : integer:=96;
constant VD : integer:=480;
constant VF : integer:=10;
constant VB : integer:=33;
constant VR : integer:=2;
signal pixel_tick_reg, pixel_tick_next : std_logic;
signal h_count_reg, h_count_next : unsigned (9 downto 0);
signal v_count_reg, v_count_next : unsigned (9 downto 0);
signal h_sync_reg, h_sync_next : std_logic;
signal v_sync_reg, v_sync_next : std_logic;
signal h_end, v_end : std_logic;
begin
process (clk,rst)
begin
if rst='1' then
pixel_tick_reg <= '0';
h_count_reg <= (others=>'0');
v_count_reg <= (others=>'0');
h_sync_reg <= '0';
v_sync_reg <= '0';
elsif (clk'event and clk='1') then
pixel_tick_reg <= pixel_tick_next;
h_count_reg <= h_count_next;
v_count_reg <= v_count_next;
h_sync_reg <= h_sync_next;
v_sync_reg <= v_sync_next;
end if;
end process;
pixel_tick_next <= not pixel_tick_reg;
h_end <=
'1' when h_count_reg=(HD+HF+HB+HR-1) else
'0';
v_end <=
'1' when v_count_reg=(VD+VF+VB+VR-1) else
'0';
process (h_count_reg,h_end,pixel_tick_reg)
begin
if pixel_tick_reg='1' then
144
if h_end='1' then
h_count_next <= (others=>'0');
else
h_count_next <= h_count_reg + 1;
end if;
else
h_count_next <= h_count_reg;
end if;
end process;
process (v_count_reg,h_end,v_end,pixel_tick_reg)
begin
if pixel_tick_reg='1' and h_end='1' then
if v_end='1' then
v_count_next <= (others=>'0');
else
v_count_next <= v_count_reg + 1;
end if;
else
v_count_next <= v_count_reg;
end if;
end process;
h_sync_next <=
'0' when (h_count_reg>=(HD+HF)) and (h_count_reg<=(HD+HF+HR-1)) else
'1';
v_sync_next <=
'0' when (v_count_reg>=(VD+VF)) and (v_count_reg<=(VD+VF+VR-1)) else
'1';
video_on <=
'1' when (h_count_reg<HD) and (v_count_reg<VD) else
'0';
h_sync <= h_sync_reg;
v_sync <= v_sync_reg;
pixel_x <= std_logic_vector(h_count_reg);
pixel_y <= std_logic_vector(v_count_reg);
p_tick <= pixel_tick_reg;
end sync_VGA;
145
Anexo I – Código em VHDL do módulo de geração de pixels
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Pixelgen_VGA is
Port ( clk : in STD_LOGIC;
video_on : in STD_LOGIC;
pixel_x, pixel_y : in STD_LOGIC_VECTOR (9 downto 0);
nota1_mod, nota2_mod, nota3_mod, nota4_mod, nota5_mod : in STD_LOGIC_VECTOR (5 downto
0);
estado : in STD_LOGIC_VECTOR (3 downto 0);
graph_rgb : out STD_LOGIC_VECTOR (7 downto 0));
end Pixelgen_VGA;
architecture pixelgen_VGA of Pixelgen_VGA is
signal pix_x, pix_y : unsigned (9 downto 0);
signal tecladob1_on, tecladob2_on, tecladob3_on, tecladob4_on, tecladob5_on, tecladob6_on,
tecladob7_on : std_logic;
signal tecladop1_on, tecladop2_on, tecladop3_on, tecladop4_on, tecladop5_on : std_logic;
signal divisao1_on, divisao2_on, divisao3_on, divisao4_on, divisao5_on, divisao6_on : std_logic;
signal marcab11_on, marcab12_on, marcab13_on, marcab14_on, marcab15_on : std_logic;
signal marcab21_on, marcab22_on, marcab23_on, marcab24_on, marcab25_on : std_logic;
signal marcab31_on, marcab32_on, marcab33_on, marcab34_on, marcab35_on : std_logic;
signal marcab41_on, marcab42_on, marcab43_on, marcab44_on, marcab45_on : std_logic;
signal marcab51_on, marcab52_on, marcab53_on, marcab54_on, marcab55_on : std_logic;
signal marcab61_on, marcab62_on, marcab63_on, marcab64_on, marcab65_on : std_logic;
signal marcab71_on, marcab72_on, marcab73_on, marcab74_on, marcab75_on : std_logic;
signal marcap11_on, marcap12_on, marcap13_on, marcap14_on, marcap15_on : std_logic;
signal marcap21_on, marcap22_on, marcap23_on, marcap24_on, marcap25_on : std_logic;
signal marcap31_on, marcap32_on, marcap33_on, marcap34_on, marcap35_on : std_logic;
signal marcap41_on, marcap42_on, marcap43_on, marcap44_on, marcap45_on : std_logic;
signal marcap51_on, marcap52_on, marcap53_on, marcap54_on, marcap55_on : std_logic;
signal divisao_rgb, tecladob_rgb, tecladop_rgb, marcabon_rgb, marcaboff_rgb, marcapon_rgb,
marcapoff_rgb, textyellow_rgb, textorange_rgb : std_logic_vector (7 downto 0);
signal rom_addr : std_logic_vector (10 downto 0);
signal font_word : std_logic_vector (7 downto 0);
signal font_bit : std_logic;
signal t_livre_on, t_gravacao_on, t_leitura_on, t_esc_on, t_menu_on, t_f1_on, t_f2_on, t_f3_on, t_f4_on,
t_memg_on, t_1_on, t_2_on, t_3_on, t_memf_on, t_meml_on, t_mema_on, t_memm_on, t_memt_on : std_logic;
signal t_qm_on, t_am_on, t_wm_on, t_em_on, t_rm_on, t_tm_on, t_ym_on, t_um_on, t_im_on, t_om_on,
t_pm_on, t_1m_on, t_2m_on, t_sm_on, t_dm_on, t_fm_on, t_gm_on, t_hm_on, t_jm_on, t_km_on, t_lm_on,
t_3m_on, t_4m_on, t_5m_on, t_enterm_on, t_escm_on : std_logic;
signal t_qt_on, t_wt_on, t_et_on, t_rt_on, t_tt_on, t_yt_on, t_ut_on, t_it_on, t_at_on, t_st_on, t_dt_on,
t_ft_on, t_gt_on, t_ht_on, t_jt_on, t_kt_on, t_entert_on, t_esct_on : std_logic;
signal char_addr, char_addr_livre, char_addr_gravacao, char_addr_leitura, char_addr_esc,
char_addr_menu, char_addr_f1, char_addr_f2, char_addr_f3, char_addr_f4, char_addr_memg, char_addr_1,
char_addr_2, char_addr_3, char_addr_memf, char_addr_meml, char_addr_mema, char_addr_memm,
char_addr_memt : std_logic_vector (6 downto 0);
signal char_addr_qm, char_addr_am, char_addr_wm, char_addr_em, char_addr_rm, char_addr_tm,
char_addr_ym, char_addr_um, char_addr_im, char_addr_om, char_addr_pm, char_addr_1m, char_addr_2m,
char_addr_sm, char_addr_dm, char_addr_fm, char_addr_gm, char_addr_hm, char_addr_jm, char_addr_km,
char_addr_lm, char_addr_3m, char_addr_4m, char_addr_5m, char_addr_enterm, char_addr_escm :
std_logic_vector (6 downto 0);
signal char_addr_qt, char_addr_wt, char_addr_et, char_addr_rt, char_addr_tt, char_addr_yt,
char_addr_ut, char_addr_it, char_addr_at, char_addr_st, char_addr_dt, char_addr_ft, char_addr_gt,
char_addr_ht, char_addr_jt, char_addr_kt, char_addr_entert, char_addr_esct : std_logic_vector (6 downto 0);
signal row_addr, row_addr_8x16, row_addr_16x32 : std_logic_vector (3 downto 0);
signal bit_addr, bit_addr_8x16, bit_addr_16x32 : std_logic_vector (2 downto 0);
146
--Teclas brancas do teclado
constant TECLADOB_X_SIZE : integer:=60;
constant TECLADOB_Y_SIZE : integer:=255;
constant TECLADOB_Y_T : integer:=140;
constant TECLADOB_Y_B : integer:=(TECLADOB_Y_T + TECLADOB_Y_SIZE - 1);
constant TECLADOB1_X_L : integer:=110;
constant TECLADOB1_X_R : integer:=(TECLADOB1_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB2_X_L : integer:=(TECLADOB1_X_L + TECLADOB_X_SIZE);
constant TECLADOB2_X_R : integer:=(TECLADOB2_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB3_X_L : integer:=(TECLADOB2_X_L + TECLADOB_X_SIZE);
constant TECLADOB3_X_R : integer:=(TECLADOB3_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB4_X_L : integer:=(TECLADOB3_X_L + TECLADOB_X_SIZE);
constant TECLADOB4_X_R : integer:=(TECLADOB4_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB5_X_L : integer:=(TECLADOB4_X_L + TECLADOB_X_SIZE);
constant TECLADOB5_X_R : integer:=(TECLADOB5_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB6_X_L : integer:=(TECLADOB5_X_L + TECLADOB_X_SIZE);
constant TECLADOB6_X_R : integer:=(TECLADOB6_X_L + TECLADOB_X_SIZE - 1);
constant TECLADOB7_X_L : integer:=(TECLADOB6_X_L + TECLADOB_X_SIZE);
constant TECLADOB7_X_R : integer:=(TECLADOB7_X_L + TECLADOB_X_SIZE - 1);
--Teclas pretas do teclado
constant TECLADOP_X_SIZE : integer:=30;
constant TECLADOP_Y_SIZE : integer:=150;
constant TECLADOP_Y_T : integer:=(TECLADOB_Y_T);
constant TECLADOP_Y_B : integer:=(TECLADOP_Y_T + TECLADOP_Y_SIZE - 1);
constant TECLADOP1_X_L : integer:=(TECLADOB1_X_R - TECLADOP_X_SIZE/2 + 1);
constant TECLADOP1_X_R : integer:=(TECLADOP1_X_L + TECLADOP_X_SIZE - 1);
constant TECLADOP2_X_L : integer:=(TECLADOB2_X_R - TECLADOP_X_SIZE/2 + 1);
constant TECLADOP2_X_R : integer:=(TECLADOP2_X_L + TECLADOP_X_SIZE - 1);
constant TECLADOP3_X_L : integer:=(TECLADOB4_X_R - TECLADOP_X_SIZE/2 + 1);
constant TECLADOP3_X_R : integer:=(TECLADOP3_X_L + TECLADOP_X_SIZE - 1);
constant TECLADOP4_X_L : integer:=(TECLADOB5_X_R - TECLADOP_X_SIZE/2 + 1);
constant TECLADOP4_X_R : integer:=(TECLADOP4_X_L + TECLADOP_X_SIZE - 1);
constant TECLADOP5_X_L : integer:=(TECLADOB6_X_R - TECLADOP_X_SIZE/2 + 1);
constant TECLADOP5_X_R : integer:=(TECLADOP5_X_L + TECLADOP_X_SIZE - 1);
--Divisões do teclado
constant DIVISAO_X_SIZE : integer:=2;
constant DIVISAO_Y_T : integer:=(TECLADOB_Y_T);
constant DIVISAO_Y_B : integer:=(TECLADOB_Y_B);
constant DIVISAO1_X_L : integer:=(TECLADOB1_X_R);
constant DIVISAO1_X_R : integer:=(DIVISAO1_X_L + DIVISAO_X_SIZE - 1);
constant DIVISAO2_X_L : integer:=(TECLADOB2_X_R);
constant DIVISAO2_X_R : integer:=(DIVISAO2_X_L + DIVISAO_X_SIZE - 1);
constant DIVISAO3_X_L : integer:=(TECLADOB3_X_R);
constant DIVISAO3_X_R : integer:=(DIVISAO3_X_L + DIVISAO_X_SIZE - 1);
constant DIVISAO4_X_L : integer:=(TECLADOB4_X_R);
constant DIVISAO4_X_R : integer:=(DIVISAO4_X_L + DIVISAO_X_SIZE - 1);
constant DIVISAO5_X_L : integer:=(TECLADOB5_X_R);
constant DIVISAO5_X_R : integer:=(DIVISAO5_X_L + DIVISAO_X_SIZE - 1);
constant DIVISAO6_X_L : integer:=(TECLADOB6_X_R);
constant DIVISAO6_X_R : integer:=(DIVISAO6_X_L + DIVISAO_X_SIZE - 1);
--Marcadores de oitavas nas teclas brancas
constant MARCAB_X_SIZE : integer:=40;
constant MARCAB_Y_SIZE : integer:=15;
constant MARCAB1_X_L : integer:=(TECLADOB1_X_L + 10);
constant MARCAB1_X_R : integer:=(MARCAB1_X_L + MARCAB_X_SIZE - 1);
constant MARCAB2_X_L : integer:=(TECLADOB2_X_L + 10);
constant MARCAB2_X_R : integer:=(MARCAB2_X_L + MARCAB_X_SIZE - 1);
constant MARCAB3_X_L : integer:=(TECLADOB3_X_L + 10);
constant MARCAB3_X_R : integer:=(MARCAB3_X_L + MARCAB_X_SIZE - 1);
constant MARCAB4_X_L : integer:=(TECLADOB4_X_L + 10);
147
constant MARCAB4_X_R : integer:=(MARCAB4_X_L + MARCAB_X_SIZE - 1);
constant MARCAB5_X_L : integer:=(TECLADOB5_X_L + 10);
constant MARCAB5_X_R : integer:=(MARCAB5_X_L + MARCAB_X_SIZE - 1);
constant MARCAB6_X_L : integer:=(TECLADOB6_X_L + 10);
constant MARCAB6_X_R : integer:=(MARCAB6_X_L + MARCAB_X_SIZE - 1);
constant MARCAB7_X_L : integer:=(TECLADOB7_X_L + 10);
constant MARCAB7_X_R : integer:=(MARCAB7_X_L + MARCAB_X_SIZE - 1);
constant MARCAB1_Y_T : integer:=(TECLADOP_Y_B + 5);
constant MARCAB1_Y_B : integer:=(MARCAB1_Y_T + MARCAB_Y_SIZE - 1);
constant MARCAB2_Y_T : integer:=(MARCAB1_Y_B + 5);
constant MARCAB2_Y_B : integer:=(MARCAB2_Y_T + MARCAB_Y_SIZE - 1);
constant MARCAB3_Y_T : integer:=(MARCAB2_Y_B + 5);
constant MARCAB3_Y_B : integer:=(MARCAB3_Y_T + MARCAB_Y_SIZE - 1);
constant MARCAB4_Y_T : integer:=(MARCAB3_Y_B + 5);
constant MARCAB4_Y_B : integer:=(MARCAB4_Y_T + MARCAB_Y_SIZE - 1);
constant MARCAB5_Y_T : integer:=(MARCAB4_Y_B + 5);
constant MARCAB5_Y_B : integer:=(MARCAB5_Y_T + MARCAB_Y_SIZE - 1);
--Marcadores de oitavas nas teclas pretas
constant MARCAP_X_SIZE : integer:=20;
constant MARCAP_Y_SIZE : integer:=15;
constant MARCAP1_X_L : integer:=(TECLADOP1_X_L + 5);
constant MARCAP1_X_R : integer:=(MARCAP1_X_L + MARCAP_X_SIZE - 1);
constant MARCAP2_X_L : integer:=(TECLADOP2_X_L + 5);
constant MARCAP2_X_R : integer:=(MARCAP2_X_L + MARCAP_X_SIZE - 1);
constant MARCAP3_X_L : integer:=(TECLADOP3_X_L + 5);
constant MARCAP3_X_R : integer:=(MARCAP3_X_L + MARCAP_X_SIZE - 1);
constant MARCAP4_X_L : integer:=(TECLADOP4_X_L + 5);
constant MARCAP4_X_R : integer:=(MARCAP4_X_L + MARCAP_X_SIZE - 1);
constant MARCAP5_X_L : integer:=(TECLADOP5_X_L + 5);
constant MARCAP5_X_R : integer:=(MARCAP5_X_L + MARCAP_X_SIZE - 1);
constant MARCAP5_Y_B : integer:=(TECLADOP_Y_B - 10);
constant MARCAP5_Y_T : integer:=(MARCAP5_Y_B - MARCAP_Y_SIZE + 1);
constant MARCAP4_Y_B : integer:=(MARCAP5_Y_T - 5);
constant MARCAP4_Y_T : integer:=(MARCAP4_Y_B - MARCAP_Y_SIZE + 1);
constant MARCAP3_Y_B : integer:=(MARCAP4_Y_T - 5);
constant MARCAP3_Y_T : integer:=(MARCAP3_Y_B - MARCAP_Y_SIZE + 1);
constant MARCAP2_Y_B : integer:=(MARCAP3_Y_T - 5);
constant MARCAP2_Y_T : integer:=(MARCAP2_Y_B - MARCAP_Y_SIZE + 1);
constant MARCAP1_Y_B : integer:=(MARCAP2_Y_T - 5);
constant MARCAP1_Y_T : integer:=(MARCAP1_Y_B - MARCAP_Y_SIZE + 1);
begin
font_rom_unit : entity work.Font_rom(font_rom)
port map (clk=>clk, addr=>rom_addr, data=>font_word);
pix_x <= unsigned(pixel_x);
pix_y <= unsigned(pixel_y);
--Teclas brancas do teclado
tecladob1_on <=
'1' when (TECLADOB1_X_L<=pix_x) and (pix_x<=TECLADOB1_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob2_on <=
'1' when (TECLADOB2_X_L<=pix_x) and (pix_x<=TECLADOB2_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob3_on <=
'1' when (TECLADOB3_X_L<=pix_x) and (pix_x<=TECLADOB3_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
148
tecladob4_on <=
'1' when (TECLADOB4_X_L<=pix_x) and (pix_x<=TECLADOB4_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob5_on <=
'1' when (TECLADOB5_X_L<=pix_x) and (pix_x<=TECLADOB5_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob6_on <=
'1' when (TECLADOB6_X_L<=pix_x) and (pix_x<=TECLADOB6_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob7_on <=
'1' when (TECLADOB7_X_L<=pix_x) and (pix_x<=TECLADOB7_X_R) and
(TECLADOB_Y_T<=pix_y) and (pix_y<=TECLADOB_Y_B) else
'0';
tecladob_rgb <= "11111111";
--Teclas pretas do teclado
tecladop1_on <=
'1' when (TECLADOP1_X_L<=pix_x) and (pix_x<=TECLADOP1_X_R) and
(TECLADOP_Y_T<=pix_y) and (pix_y<=TECLADOP_Y_B) else
'0';
tecladop2_on <=
'1' when (TECLADOP2_X_L<=pix_x) and (pix_x<=TECLADOP2_X_R) and
(TECLADOP_Y_T<=pix_y) and (pix_y<=TECLADOP_Y_B) else
'0';
tecladop3_on <=
'1' when (TECLADOP3_X_L<=pix_x) and (pix_x<=TECLADOP3_X_R) and
(TECLADOP_Y_T<=pix_y) and (pix_y<=TECLADOP_Y_B) else
'0';
tecladop4_on <=
'1' when (TECLADOP4_X_L<=pix_x) and (pix_x<=TECLADOP4_X_R) and
(TECLADOP_Y_T<=pix_y) and (pix_y<=TECLADOP_Y_B) else
'0';
tecladop5_on <=
'1' when (TECLADOP5_X_L<=pix_x) and (pix_x<=TECLADOP5_X_R) and
(TECLADOP_Y_T<=pix_y) and (pix_y<=TECLADOP_Y_B) else
'0';
tecladop_rgb <= "00000000";
--Divisões do teclado
divisao1_on <=
'1' when (DIVISAO1_X_L<=pix_x) and (pix_x<=DIVISAO1_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
divisao2_on <=
'1' when (DIVISAO2_X_L<=pix_x) and (pix_x<=DIVISAO2_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
divisao3_on <=
'1' when (DIVISAO3_X_L<=pix_x) and (pix_x<=DIVISAO3_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
divisao4_on <=
'1' when (DIVISAO4_X_L<=pix_x) and (pix_x<=DIVISAO4_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
divisao5_on <=
'1' when (DIVISAO5_X_L<=pix_x) and (pix_x<=DIVISAO5_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
149
divisao6_on <=
'1' when (DIVISAO6_X_L<=pix_x) and (pix_x<=DIVISAO6_X_R) and
(DIVISAO_Y_T<=pix_y) and (pix_y<=DIVISAO_Y_B) else
'0';
divisao_rgb <= "00000000";
--Marcadores de oitavas nas teclas brancas
marcab11_on <=
'1' when (MARCAB1_X_L<=pix_x) and (pix_x<=MARCAB1_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab12_on <=
'1' when (MARCAB1_X_L<=pix_x) and (pix_x<=MARCAB1_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab13_on <=
'1' when (MARCAB1_X_L<=pix_x) and (pix_x<=MARCAB1_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab14_on <=
'1' when (MARCAB1_X_L<=pix_x) and (pix_x<=MARCAB1_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab15_on <=
'1' when (MARCAB1_X_L<=pix_x) and (pix_x<=MARCAB1_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab21_on <=
'1' when (MARCAB2_X_L<=pix_x) and (pix_x<=MARCAB2_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab22_on <=
'1' when (MARCAB2_X_L<=pix_x) and (pix_x<=MARCAB2_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab23_on <=
'1' when (MARCAB2_X_L<=pix_x) and (pix_x<=MARCAB2_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab24_on <=
'1' when (MARCAB2_X_L<=pix_x) and (pix_x<=MARCAB2_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab25_on <=
'1' when (MARCAB2_X_L<=pix_x) and (pix_x<=MARCAB2_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab31_on <=
'1' when (MARCAB3_X_L<=pix_x) and (pix_x<=MARCAB3_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab32_on <=
'1' when (MARCAB3_X_L<=pix_x) and (pix_x<=MARCAB3_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab33_on <=
'1' when (MARCAB3_X_L<=pix_x) and (pix_x<=MARCAB3_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab34_on <=
150
'1' when (MARCAB3_X_L<=pix_x) and (pix_x<=MARCAB3_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab35_on <=
'1' when (MARCAB3_X_L<=pix_x) and (pix_x<=MARCAB3_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab41_on <=
'1' when (MARCAB4_X_L<=pix_x) and (pix_x<=MARCAB4_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab42_on <=
'1' when (MARCAB4_X_L<=pix_x) and (pix_x<=MARCAB4_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab43_on <=
'1' when (MARCAB4_X_L<=pix_x) and (pix_x<=MARCAB4_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab44_on <=
'1' when (MARCAB4_X_L<=pix_x) and (pix_x<=MARCAB4_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab45_on <=
'1' when (MARCAB4_X_L<=pix_x) and (pix_x<=MARCAB4_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab51_on <=
'1' when (MARCAB5_X_L<=pix_x) and (pix_x<=MARCAB5_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab52_on <=
'1' when (MARCAB5_X_L<=pix_x) and (pix_x<=MARCAB5_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab53_on <=
'1' when (MARCAB5_X_L<=pix_x) and (pix_x<=MARCAB5_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab54_on <=
'1' when (MARCAB5_X_L<=pix_x) and (pix_x<=MARCAB5_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab55_on <=
'1' when (MARCAB5_X_L<=pix_x) and (pix_x<=MARCAB5_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab61_on <=
'1' when (MARCAB6_X_L<=pix_x) and (pix_x<=MARCAB6_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab62_on <=
'1' when (MARCAB6_X_L<=pix_x) and (pix_x<=MARCAB6_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab63_on <=
'1' when (MARCAB6_X_L<=pix_x) and (pix_x<=MARCAB6_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab64_on <=
151
'1' when (MARCAB6_X_L<=pix_x) and (pix_x<=MARCAB6_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab65_on <=
'1' when (MARCAB6_X_L<=pix_x) and (pix_x<=MARCAB6_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcab71_on <=
'1' when (MARCAB7_X_L<=pix_x) and (pix_x<=MARCAB7_X_R) and
(MARCAB1_Y_T<=pix_y) and (pix_y<=MARCAB1_Y_B) else
'0';
marcab72_on <=
'1' when (MARCAB7_X_L<=pix_x) and (pix_x<=MARCAB7_X_R) and
(MARCAB2_Y_T<=pix_y) and (pix_y<=MARCAB2_Y_B) else
'0';
marcab73_on <=
'1' when (MARCAB7_X_L<=pix_x) and (pix_x<=MARCAB7_X_R) and
(MARCAB3_Y_T<=pix_y) and (pix_y<=MARCAB3_Y_B) else
'0';
marcab74_on <=
'1' when (MARCAB7_X_L<=pix_x) and (pix_x<=MARCAB7_X_R) and
(MARCAB4_Y_T<=pix_y) and (pix_y<=MARCAB4_Y_B) else
'0';
marcab75_on <=
'1' when (MARCAB7_X_L<=pix_x) and (pix_x<=MARCAB7_X_R) and
(MARCAB5_Y_T<=pix_y) and (pix_y<=MARCAB5_Y_B) else
'0';
marcabon_rgb <= "00000100";
marcaboff_rgb <= "10101101";
--Marcadores de oitavas nas teclas pretas
marcap11_on <=
'1' when (MARCAP1_X_L<=pix_x) and (pix_x<=MARCAP1_X_R) and
(MARCAP1_Y_T<=pix_y) and (pix_y<=MARCAP1_Y_B) else
'0';
marcap12_on <=
'1' when (MARCAP1_X_L<=pix_x) and (pix_x<=MARCAP1_X_R) and
(MARCAP2_Y_T<=pix_y) and (pix_y<=MARCAP2_Y_B) else
'0';
marcap13_on <=
'1' when (MARCAP1_X_L<=pix_x) and (pix_x<=MARCAP1_X_R) and
(MARCAP3_Y_T<=pix_y) and (pix_y<=MARCAP3_Y_B) else
'0';
marcap14_on <=
'1' when (MARCAP1_X_L<=pix_x) and (pix_x<=MARCAP1_X_R) and
(MARCAP4_Y_T<=pix_y) and (pix_y<=MARCAP4_Y_B) else
'0';
marcap15_on <=
'1' when (MARCAP1_X_L<=pix_x) and (pix_x<=MARCAP1_X_R) and
(MARCAP5_Y_T<=pix_y) and (pix_y<=MARCAP5_Y_B) else
'0';
marcap21_on <=
'1' when (MARCAP2_X_L<=pix_x) and (pix_x<=MARCAP2_X_R) and
(MARCAP1_Y_T<=pix_y) and (pix_y<=MARCAP1_Y_B) else
'0';
marcap22_on <=
'1' when (MARCAP2_X_L<=pix_x) and (pix_x<=MARCAP2_X_R) and
(MARCAP2_Y_T<=pix_y) and (pix_y<=MARCAP2_Y_B) else
'0';
marcap23_on <=
152
'1' when (MARCAP2_X_L<=pix_x) and (pix_x<=MARCAP2_X_R) and
(MARCAP3_Y_T<=pix_y) and (pix_y<=MARCAP3_Y_B) else
'0';
marcap24_on <=
'1' when (MARCAP2_X_L<=pix_x) and (pix_x<=MARCAP2_X_R) and
(MARCAP4_Y_T<=pix_y) and (pix_y<=MARCAP4_Y_B) else
'0';
marcap25_on <=
'1' when (MARCAP2_X_L<=pix_x) and (pix_x<=MARCAP2_X_R) and
(MARCAP5_Y_T<=pix_y) and (pix_y<=MARCAP5_Y_B) else
'0';
marcap31_on <=
'1' when (MARCAP3_X_L<=pix_x) and (pix_x<=MARCAP3_X_R) and
(MARCAP1_Y_T<=pix_y) and (pix_y<=MARCAP1_Y_B) else
'0';
marcap32_on <=
'1' when (MARCAP3_X_L<=pix_x) and (pix_x<=MARCAP3_X_R) and
(MARCAP2_Y_T<=pix_y) and (pix_y<=MARCAP2_Y_B) else
'0';
marcap33_on <=
'1' when (MARCAP3_X_L<=pix_x) and (pix_x<=MARCAP3_X_R) and
(MARCAP3_Y_T<=pix_y) and (pix_y<=MARCAP3_Y_B) else
'0';
marcap34_on <=
'1' when (MARCAP3_X_L<=pix_x) and (pix_x<=MARCAP3_X_R) and
(MARCAP4_Y_T<=pix_y) and (pix_y<=MARCAP4_Y_B) else
'0';
marcap35_on <=
'1' when (MARCAP3_X_L<=pix_x) and (pix_x<=MARCAP3_X_R) and
(MARCAP5_Y_T<=pix_y) and (pix_y<=MARCAP5_Y_B) else
'0';
marcap41_on <=
'1' when (MARCAP4_X_L<=pix_x) and (pix_x<=MARCAP4_X_R) and
(MARCAP1_Y_T<=pix_y) and (pix_y<=MARCAP1_Y_B) else
'0';
marcap42_on <=
'1' when (MARCAP4_X_L<=pix_x) and (pix_x<=MARCAP4_X_R) and
(MARCAP2_Y_T<=pix_y) and (pix_y<=MARCAP2_Y_B) else
'0';
marcap43_on <=
'1' when (MARCAP4_X_L<=pix_x) and (pix_x<=MARCAP4_X_R) and
(MARCAP3_Y_T<=pix_y) and (pix_y<=MARCAP3_Y_B) else
'0';
marcap44_on <=
'1' when (MARCAP4_X_L<=pix_x) and (pix_x<=MARCAP4_X_R) and
(MARCAP4_Y_T<=pix_y) and (pix_y<=MARCAP4_Y_B) else
'0';
marcap45_on <=
'1' when (MARCAP4_X_L<=pix_x) and (pix_x<=MARCAP4_X_R) and
(MARCAP5_Y_T<=pix_y) and (pix_y<=MARCAP5_Y_B) else
'0';
marcap51_on <=
'1' when (MARCAP5_X_L<=pix_x) and (pix_x<=MARCAP5_X_R) and
(MARCAP1_Y_T<=pix_y) and (pix_y<=MARCAP1_Y_B) else
'0';
marcap52_on <=
'1' when (MARCAP5_X_L<=pix_x) and (pix_x<=MARCAP5_X_R) and
(MARCAP2_Y_T<=pix_y) and (pix_y<=MARCAP2_Y_B) else
'0';
marcap53_on <=
153
'1' when (MARCAP5_X_L<=pix_x) and (pix_x<=MARCAP5_X_R) and
(MARCAP3_Y_T<=pix_y) and (pix_y<=MARCAP3_Y_B) else
'0';
marcap54_on <=
'1' when (MARCAP5_X_L<=pix_x) and (pix_x<=MARCAP5_X_R) and
(MARCAP4_Y_T<=pix_y) and (pix_y<=MARCAP4_Y_B) else
'0';
marcap55_on <=
'1' when (MARCAP5_X_L<=pix_x) and (pix_x<=MARCAP5_X_R) and
(MARCAP5_Y_T<=pix_y) and (pix_y<=MARCAP5_Y_B) else
'0';
marcapon_rgb <= "00000100";
marcapoff_rgb <= "01010010";
--Texto "Sintetizador de Sons"
-- " Menu "
t_menu_on <=
'1' when (3<=pix_y(9 downto 5) and pix_y(9 downto 5)<=4) and (10<=pix_x(9 downto 4) and
pix_x(9 downto 4)<=29) else
'0';
with (pix_y(7) & pix_x(8 downto 4)) select
char_addr_menu <=
"1010011" when "001010", --S
"1101001" when "001011", --i
"1101110" when "001100", --n
"1110100" when "001101", --t
"1100101" when "001110", --e
"1110100" when "001111", --t
"1101001" when "010000", --i
"1111010" when "010001", --z
"1100001" when "010010", --a
"1100100" when "010011", --d
"1101111" when "010100", --o
"1110010" when "010101", --r
"0000000" when "010110", --
"1100100" when "010111", --d
"1100101" when "011000", --e
"0000000" when "011001", --
"1010011" when "011010", --S
"1101111" when "011011", --o
"1101110" when "011100", --n
"1110011" when "011101", --s
"0000000" when "101010", --
"0000000" when "101011", --
"0000000" when "101100", --
"0000000" when "101101", --
"0000000" when "101110", --
"0000000" when "101111", --
"0000000" when "110000", --
"0000000" when "110001", --
"1001101" when "110010", --M
"1100101" when "110011", --e
"1101110" when "110100", --n
"1110101" when "110101", --u
"0000000" when "110110", --
"0000000" when "110111", --
"0000000" when "111000", --
"0000000" when "111001", --
"0000000" when "111010", --
"0000000" when "111011", --
"0000000" when "111100", --
154
"0000000" when others; --
--Texto "F1 -> Modo Livre"
t_f1_on <=
'1' when (pix_y(9 downto 4)=14) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=44) else
'0';
with pix_x(8 downto 3) select
char_addr_f1 <=
"1000110" when "011110", --F
"0110001" when "011111", --1
"0000000" when "100000", --
"0011010" when "100001", -->
"0000000" when "100010", --
"1001101" when "100011", --M
"1101111" when "100100", --o
"1100100" when "100101", --d
"1101111" when "100110", --o
"0000000" when "100111", --
"1001100" when "101000", --L
"1101001" when "101001", --i
"1110110" when "101010", --v
"1110010" when "101011", --r
"1100101" when others; --e
--Texto "F2 -> Modo de Gravação"
t_f2_on <=
'1' when (pix_y(9 downto 4)=17) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=50) else
'0';
with pix_x(8 downto 3) select
char_addr_f2 <=
"1000110" when "011110", --F
"0110010" when "011111", --2
"0000000" when "100000", --
"0011010" when "100001", -->
"0000000" when "100010", --
"1001101" when "100011", --M
"1101111" when "100100", --o
"1100100" when "100101", --d
"1101111" when "100110", --o
"0000000" when "100111", --
"1100100" when "101000", --d
"1100101" when "101001", --e
"0000000" when "101010", --
"1000111" when "101011", --G
"1110010" when "101100", --r
"1100001" when "101101", --a
"1110110" when "101110", --v
"1100001" when "101111", --a
"0000010" when "110000", --ç
"0000001" when "110001", --ã
"1101111" when others; --o
--Texto "F3 -> Modo de Leitura"
t_f3_on <=
'1' when (pix_y(9 downto 4)=20) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=49) else
'0';
with pix_x(8 downto 3) select
char_addr_f3 <=
"1000110" when "011110", --F
"0110011" when "011111", --3
"0000000" when "100000", --
"0011010" when "100001", -->
"0000000" when "100010", --
155
"1001101" when "100011", --M
"1101111" when "100100", --o
"1100100" when "100101", --d
"1101111" when "100110", --o
"0000000" when "100111", --
"1100100" when "101000", --d
"1100101" when "101001", --e
"0000000" when "101010", --
"1001100" when "101011", --L
"1100101" when "101100", --e
"1101001" when "101101", --i
"1110100" when "101110", --t
"1110101" when "101111", --u
"1110010" when "110000", --r
"1100001" when others; --a
--Texto "F4 -> Apagar Memórias"
t_f4_on <=
'1' when (pix_y(9 downto 4)=23) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=49) else
'0';
with pix_x(8 downto 3) select
char_addr_f4 <=
"1000110" when "011110", --F
"0110100" when "011111", --4
"0000000" when "100000", --
"0011010" when "100001", -->
"0000000" when "100010", --
"1000001" when "100011", --A
"1110000" when "100100", --p
"1100001" when "100101", --a
"1100111" when "100110", --g
"1100001" when "100111", --a
"1110010" when "101000", --r
"0000000" when "101001", --
"1001101" when "101010", --M
"1100101" when "101011", --e
"1101101" when "101100", --m
"0000011" when "101101", --ó
"1110010" when "101110", --r
"1101001" when "101111", --i
"1100001" when "110000", --a
"1110011" when others; --s
--Texto "Modo Livre"
t_livre_on <=
'1' when (pix_y(9 downto 5)=2) and (15<=pix_x(9 downto 4) and pix_x(9 downto 4)<=24) else
'0';
with pix_x(8 downto 4) select
char_addr_livre <=
"1001101" when "01111", --M
"1101111" when "10000", --o
"1100100" when "10001", --d
"1101111" when "10010", --o
"0000000" when "10011", --
"1001100" when "10100", --L
"1101001" when "10101", --i
"1110110" when "10110", --v
"1110010" when "10111", --r
"1100101" when others; --e
--Texto "Modo de Gravação"
t_gravacao_on <=
'1' when (pix_y(9 downto 5)=2) and (12<=pix_x(9 downto 4) and pix_x(9 downto 4)<=27) else
156
'0';
with pix_x(8 downto 4) select
char_addr_gravacao <=
"1001101" when "01100", --M
"1101111" when "01101", --o
"1100100" when "01110", --d
"1101111" when "01111", --o
"0000000" when "10000", --
"1100100" when "10001", --d
"1100101" when "10010", --e
"0000000" when "10011", --
"1000111" when "10100", --G
"1110010" when "10101", --r
"1100001" when "10110", --a
"1110110" when "10111", --v
"1100001" when "11000", --a
"0000010" when "11001", --ç
"0000001" when "11010", --ã
"1101111" when others; --o
--Texto "Modo de Leitura"
t_leitura_on <=
'1' when (pix_y(9 downto 5)=2) and (12<=pix_x(9 downto 4) and pix_x(9 downto 4)<=26) else
'0';
with pix_x(8 downto 4) select
char_addr_leitura <=
"1001101" when "01100", --M
"1101111" when "01101", --o
"1100100" when "01110", --d
"1101111" when "01111", --o
"0000000" when "10000", --
"1100100" when "10001", --d
"1100101" when "10010", --e
"0000000" when "10011", --
"1001100" when "10100", --L
"1100101" when "10101", --e
"1101001" when "10110", --i
"1110100" when "10111", --t
"1110101" when "11000", --u
"1110010" when "11001", --r
"1100001" when others; --a
--Texto "Esc -> Menu"
t_esc_on <=
'1' when (pix_y(9 downto 4)=28) and (67<=pix_x(9 downto 3) and pix_x(9 downto 3)<=76) else
'0';
with pix_x(9 downto 3) select
char_addr_esc <=
"1000101" when "1000011", --E
"1110011" when "1000100", --s
"1100011" when "1000101", --c
"0000000" when "1000110", --
"0011010" when "1000111", -->
"0000000" when "1001000", --
"1001101" when "1001001", --M
"1100101" when "1001010", --e
"1101110" when "1001011", --n
"1110101" when others; --u
--Texto "Escolha da Memória para Gravação"
t_memg_on <=
'1' when (pix_y(9 downto 5)=3) and (4<=pix_x(9 downto 4) and pix_x(9 downto 4)<=35) else
'0';
157
with pix_x(9 downto 4) select
char_addr_memg <=
"1000101" when "000100", --E
"1110011" when "000101", --s
"1100011" when "000110", --c
"1101111" when "000111", --o
"1101100" when "001000", --l
"1101000" when "001001", --h
"1100001" when "001010", --a
"0000000" when "001011", --
"1100100" when "001100", --d
"1100001" when "001101", --a
"0000000" when "001110", --
"1001101" when "001111", --M
"1100101" when "010000", --e
"1101101" when "010001", --m
"0000011" when "010010", --ó
"1110010" when "010011", --r
"1101001" when "010100", --i
"1100001" when "010101", --a
"0000000" when "010110", --
"1110000" when "010111", --p
"1100001" when "011000", --a
"1110010" when "011001", --r
"1100001" when "011010", --a
"0000000" when "011011", --
"1000111" when "011100", --G
"1110010" when "011101", --r
"1100001" when "011110", --a
"1110110" when "011111", --v
"1100001" when "100000", --a
"0000010" when "100001", --ç
"0000001" when "100010", --ã
"1101111" when others; --o
--Texto "1 -> Memória 1"
t_1_on <=
'1' when (pix_y(9 downto 4)=14) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=42) else
'0';
with pix_x(8 downto 3) select
char_addr_1 <=
"0110001" when "011110", --1
"0000000" when "011111", --
"0011010" when "100000", -->
"0000000" when "100001", --
"1001101" when "100010", --M
"1100101" when "100011", --e
"1101101" when "100100", --m
"0000011" when "100101", --ó
"1110010" when "100110", --r
"1101001" when "100111", --i
"1100001" when "101000", --a
"0000000" when "101001", --
"0110001" when others; --1
--Texto "2 -> Memória 2"
t_2_on <=
'1' when (pix_y(9 downto 4)=17) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=42) else
'0';
with pix_x(8 downto 3) select
char_addr_2 <=
"0110010" when "011110", --2
158
"0000000" when "011111", --
"0011010" when "100000", -->
"0000000" when "100001", --
"1001101" when "100010", --M
"1100101" when "100011", --e
"1101101" when "100100", --m
"0000011" when "100101", --ó
"1110010" when "100110", --r
"1101001" when "100111", --i
"1100001" when "101000", --a
"0000000" when "101001", --
"0110010" when others; --2
--Texto "3 -> Memória 3"
t_3_on <=
'1' when (pix_y(9 downto 4)=20) and (30<=pix_x(9 downto 3) and pix_x(9 downto 3)<=42) else
'0';
with pix_x(8 downto 3) select
char_addr_3 <=
"0110011" when "011110", --3
"0000000" when "011111", --
"0011010" when "100000", -->
"0000000" when "100001", --
"1001101" when "100010", --M
"1100101" when "100011", --e
"1101101" when "100100", --m
"0000011" when "100101", --ó
"1110010" when "100110", --r
"1101001" when "100111", --i
"1100001" when "101000", --a
"0000000" when "101001", --
"0110011" when others; --3
--Texto "Memória Cheia"
t_memf_on <=
'1' when (pix_y(9 downto 5)=6) and (13<=pix_x(9 downto 4) and pix_x(9 downto 4)<=25) else
'0';
with pix_x(9 downto 4) select
char_addr_memf <=
"1001101" when "001101", --M
"1100101" when "001110", --e
"1101101" when "001111", --m
"0000011" when "010000", --ó
"1110010" when "010001", --r
"1101001" when "010010", --i
"1100001" when "010011", --a
"0000000" when "010100", --
"1000011" when "010101", --C
"1101000" when "010110", --h
"1100101" when "010111", --e
"1101001" when "011000", --i
"1100001" when others; --a
--Texto "Escolha da Memória para Leitura"
t_meml_on <=
'1' when (pix_y(9 downto 5)=3) and (5<=pix_x(9 downto 4) and pix_x(9 downto 4)<=35) else
'0';
with pix_x(9 downto 4) select
char_addr_meml <=
"1000101" when "000101", --E
"1110011" when "000110", --s
"1100011" when "000111", --c
"1101111" when "001000", --o
159
"1101100" when "001001", --l
"1101000" when "001010", --h
"1100001" when "001011", --a
"0000000" when "001100", --
"1100100" when "001101", --d
"1100001" when "001110", --a
"0000000" when "001111", --
"1001101" when "010000", --M
"1100101" when "010001", --e
"1101101" when "010010", --m
"0000011" when "010011", --ó
"1110010" when "010100", --r
"1101001" when "010101", --i
"1100001" when "010110", --a
"0000000" when "010111", --
"1110000" when "011000", --p
"1100001" when "011001", --a
"1110010" when "011010", --r
"1100001" when "011011", --a
"0000000" when "011100", --
"1001100" when "011101", --L
"1100101" when "011110", --e
"1101001" when "011111", --i
"1110100" when "100000", --t
"1110101" when "100001", --u
"1110010" when "100010", --r
"1100001" when others; --a
--Texto "Apagando Memórias"
t_mema_on <=
'1' when (pix_y(9 downto 5)=6) and (11<=pix_x(9 downto 4) and pix_x(9 downto 4)<=27) else
'0';
with pix_x(9 downto 4) select
char_addr_mema <=
"1000001" when "001011", --A
"1110000" when "001100", --p
"1100001" when "001101", --a
"1100111" when "001110", --g
"1100001" when "001111", --a
"1101110" when "010000", --n
"1100100" when "010001", --d
"1101111" when "010010", --o
"0000000" when "010011", --
"1001101" when "010100", --M
"1100101" when "010101", --e
"1101101" when "010110", --m
"0000011" when "010111", --ó
"1110010" when "011000", --r
"1101001" when "011001", --i
"1100001" when "011010", --a
"1110011" when others; --s
--Texto "Escolha da Modulação para Leitura"
t_memm_on <=
'1' when (pix_y(9 downto 5)=1) and (4<=pix_x(9 downto 4) and pix_x(9 downto 4)<=36) else
'0';
with pix_x(9 downto 4) select
char_addr_memm <=
"1000101" when "000100", --E
"1110011" when "000101", --s
"1100011" when "000110", --c
"1101111" when "000111", --o
160
"1101100" when "001000", --l
"1101000" when "001001", --h
"1100001" when "001010", --a
"0000000" when "001011", --
"1100100" when "001100", --d
"1100001" when "001101", --a
"0000000" when "001110", --
"1001101" when "001111", --M
"1101111" when "010000", --o
"1100100" when "010001", --d
"1110101" when "010010", --u
"1101100" when "010011", --l
"1100001" when "010100", --a
"0000010" when "010101", --ç
"0000001" when "010110", --ã
"1101111" when "010111", --o
"0000000" when "011000", --
"1110000" when "011001", --p
"1100001" when "011010", --a
"1110010" when "011011", --r
"1100001" when "011100", --a
"0000000" when "011101", --
"1001100" when "011110", --L
"1100101" when "011111", --e
"1101001" when "100000", --i
"1110100" when "100001", --t
"1110101" when "100010", --u
"1110010" when "100011", --r
"1100001" when others; --a
--Texto "Escolha do Tempo para Leitura"
t_memt_on <=
'1' when (pix_y(9 downto 5)=1) and (5<=pix_x(9 downto 4) and pix_x(9 downto 4)<=33) else
'0';
with pix_x(9 downto 4) select
char_addr_memt <=
"1000101" when "000101", --E
"1110011" when "000110", --s
"1100011" when "000111", --c
"1101111" when "001000", --o
"1101100" when "001001", --l
"1101000" when "001010", --h
"1100001" when "001011", --a
"0000000" when "001100", --
"1100100" when "001101", --d
"1101111" when "001110", --o
"0000000" when "001111", --
"1010100" when "010000", --T
"1100101" when "010001", --e
"1101101" when "010010", --m
"1110000" when "010011", --p
"1101111" when "010100", --o
"0000000" when "010101", --
"1110000" when "010110", --p
"1100001" when "010111", --a
"1110010" when "011000", --r
"1100001" when "011001", --a
"0000000" when "011010", --
"1001100" when "011011", --L
"1100101" when "011100", --e
"1101001" when "011101", --i
161
"1110100" when "011110", --t
"1110101" when "011111", --u
"1110010" when "100000", --r
"1100001" when others; --a
--Texto "Q -> Meio tom acima";
t_qm_on <=
'1' when (pix_y(9 downto 4)=5) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=27) else
'0';
with pix_x(7 downto 3) select
char_addr_qm <=
"1010001" when "01010", --Q
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1001101" when "01110", --M
"1100101" when "01111", --e
"1101001" when "10000", --i
"1101111" when "10001", --o
"0000000" when "10010", --
"1110100" when "10011", --t
"1101111" when "10100", --o
"1101101" when "10101", --m
"0000000" when "10110", --
"1100001" when "10111", --a
"1100011" when "11000", --c
"1101001" when "11001", --i
"1101101" when "11010", --m
"1100001" when others; --a
--Texto "W -> Um tom acima";
t_wm_on <=
'1' when (pix_y(9 downto 4)=7) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=25) else
'0';
with pix_x(7 downto 3) select
char_addr_wm <=
"1010111" when "01010", --W
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1010101" when "01110", --U
"1101101" when "01111", --m
"0000000" when "10000", --
"1110100" when "10001", --t
"1101111" when "10010", --o
"1101101" when "10011", --m
"0000000" when "10100", --
"1100001" when "10101", --a
"1100011" when "10110", --c
"1101001" when "10111", --i
"1101101" when "11000", --m
"1100001" when others; --a
--Texto "E -> Um tom e meio acima";
t_em_on <=
'1' when (pix_y(9 downto 4)=9) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=32) else
'0';
with pix_x(8 downto 3) select
char_addr_em <=
"1000101" when "001010", --E
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
162
"1010101" when "001110", --U
"1101101" when "001111", --m
"0000000" when "010000", --
"1110100" when "010001", --t
"1101111" when "010010", --o
"1101101" when "010011", --m
"0000000" when "010100", --
"1100101" when "010101", --e
"0000000" when "010110", --
"1101101" when "010111", --m
"1100101" when "011000", --e
"1101001" when "011001", --i
"1101111" when "011010", --o
"0000000" when "011011", --
"1100001" when "011100", --a
"1100011" when "011101", --c
"1101001" when "011110", --i
"1101101" when "011111", --m
"1100001" when others; --a
--Texto "R -> Dois tons acima";
t_rm_on <=
'1' when (pix_y(9 downto 4)=11) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=28) else
'0';
with pix_x(7 downto 3) select
char_addr_rm <=
"1010010" when "01010", --R
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1000100" when "01110", --D
"1101111" when "01111", --o
"1101001" when "10000", --i
"1110011" when "10001", --s
"0000000" when "10010", --
"1110100" when "10011", --t
"1101111" when "10100", --o
"1101110" when "10101", --n
"1110011" when "10110", --s
"0000000" when "10111", --
"1100001" when "11000", --a
"1100011" when "11001", --c
"1101001" when "11010", --i
"1101101" when "11011", --m
"1100001" when others; --a
--Texto "T -> Dois tons e meio acima";
t_tm_on <=
'1' when (pix_y(9 downto 4)=13) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=35) else
'0';
with pix_x(8 downto 3) select
char_addr_tm <=
"1010100" when "001010", --T
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1000100" when "001110", --D
"1101111" when "001111", --o
"1101001" when "010000", --i
"1110011" when "010001", --s
"0000000" when "010010", --
"1110100" when "010011", --t
163
"1101111" when "010100", --o
"1101110" when "010101", --n
"1110011" when "010110", --s
"0000000" when "010111", --
"1100101" when "011000", --e
"0000000" when "011001", --
"1101101" when "011010", --m
"1100101" when "011011", --e
"1101001" when "011100", --i
"1101111" when "011101", --o
"0000000" when "011110", --
"1100001" when "011111", --a
"1100011" when "100000", --c
"1101001" when "100001", --i
"1101101" when "100010", --m
"1100001" when others; --a
--Texto "Y -> Três tons acima";
t_ym_on <=
'1' when (pix_y(9 downto 4)=15) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=28) else
'0';
with pix_x(7 downto 3) select
char_addr_ym <=
"1011001" when "01010", --Y
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1010100" when "01110", --T
"1110010" when "01111", --r
"0000100" when "10000", --ê
"1110011" when "10001", --s
"0000000" when "10010", --
"1110100" when "10011", --t
"1101111" when "10100", --o
"1101110" when "10101", --n
"1110011" when "10110", --s
"0000000" when "10111", --
"1100001" when "11000", --a
"1100011" when "11001", --c
"1101001" when "11010", --i
"1101101" when "11011", --m
"1100001" when others; --a
--Texto "U -> Três tons e meio acima";
t_um_on <=
'1' when (pix_y(9 downto 4)=17) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=35) else
'0';
with pix_x(8 downto 3) select
char_addr_um <=
"1010101" when "001010", --U
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1110010" when "001111", --r
"0000100" when "010000", --ê
"1110011" when "010001", --s
"0000000" when "010010", --
"1110100" when "010011", --t
"1101111" when "010100", --o
"1101110" when "010101", --n
"1110011" when "010110", --s
164
"0000000" when "010111", --
"1100101" when "011000", --e
"0000000" when "011001", --
"1101101" when "011010", --m
"1100101" when "011011", --e
"1101001" when "011100", --i
"1101111" when "011101", --o
"0000000" when "011110", --
"1100001" when "011111", --a
"1100011" when "100000", --c
"1101001" when "100001", --i
"1101101" when "100010", --m
"1100001" when others; --a
--Texto "I -> Quatro tons acima";
t_im_on <=
'1' when (pix_y(9 downto 4)=19) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=30) else
'0';
with pix_x(7 downto 3) select
char_addr_im <=
"1001001" when "01010", --I
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1010001" when "01110", --Q
"1110101" when "01111", --u
"1100001" when "10000", --a
"1110100" when "10001", --t
"1110010" when "10010", --r
"1101111" when "10011", --o
"0000000" when "10100", --
"1110100" when "10101", --t
"1101111" when "10110", --o
"1101110" when "10111", --n
"1110011" when "11000", --s
"0000000" when "11001", --
"1100001" when "11010", --a
"1100011" when "11011", --c
"1101001" when "11100", --i
"1101101" when "11101", --m
"1100001" when others; --a
--Texto "O -> Quatro tons e meio acima";
t_om_on <=
'1' when (pix_y(9 downto 4)=21) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=37) else
'0';
with pix_x(8 downto 3) select
char_addr_om <=
"1001111" when "001010", --O
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010001" when "001110", --Q
"1110101" when "001111", --u
"1100001" when "010000", --a
"1110100" when "010001", --t
"1110010" when "010010", --r
"1101111" when "010011", --o
"0000000" when "010100", --
"1110100" when "010101", --t
"1101111" when "010110", --o
"1101110" when "010111", --n
165
"1110011" when "011000", --s
"0000000" when "011001", --
"1100101" when "011010", --e
"0000000" when "011011", --
"1101101" when "011100", --m
"1100101" when "011101", --e
"1101001" when "011110", --i
"1101111" when "011111", --o
"0000000" when "100000", --
"1100001" when "100001", --a
"1100011" when "100010", --c
"1101001" when "100011", --i
"1101101" when "100100", --m
"1100001" when others; --a
--Texto "P -> Cinco tons acima";
t_pm_on <=
'1' when (pix_y(9 downto 4)=23) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=29) else
'0';
with pix_x(7 downto 3) select
char_addr_pm <=
"1010000" when "01010", --P
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1000011" when "01110", --C
"1101001" when "01111", --i
"1101110" when "10000", --n
"1100011" when "10001", --c
"1101111" when "10010", --o
"0000000" when "10011", --
"1110100" when "10100", --t
"1101111" when "10101", --o
"1101110" when "10110", --n
"1110011" when "10111", --s
"0000000" when "11000", --
"1100001" when "11001", --a
"1100011" when "11010", --c
"1101001" when "11011", --i
"1101101" when "11100", --m
"1100001" when others; --a
--Texto "´ -> Cinco tons e meio acima";
t_1m_on <=
'1' when (pix_y(9 downto 4)=25) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=36) else
'0';
with pix_x(8 downto 3) select
char_addr_1m <=
"1111111" when "001010", --´
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1000011" when "001110", --C
"1101001" when "001111", --i
"1101110" when "010000", --n
"1100011" when "010001", --c
"1101111" when "010010", --o
"0000000" when "010011", --
"1110100" when "010100", --t
"1101111" when "010101", --o
"1101110" when "010110", --n
"1110011" when "010111", --s
166
"0000000" when "011000", --
"1100101" when "011001", --e
"0000000" when "011010", --
"1101101" when "011011", --m
"1100101" when "011100", --e
"1101001" when "011101", --i
"1101111" when "011110", --o
"0000000" when "011111", --
"1100001" when "100000", --a
"1100011" when "100001", --c
"1101001" when "100010", --i
"1101101" when "100011", --m
"1100001" when others; --a
--Texto "[ -> Uma oitava acima";
t_2m_on <=
'1' when (pix_y(9 downto 4)=27) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=29) else
'0';
with pix_x(7 downto 3) select
char_addr_2m <=
"1011011" when "01010", --[
"0000000" when "01011", --
"0011010" when "01100", -->
"0000000" when "01101", --
"1010101" when "01110", --U
"1101101" when "01111", --m
"1100001" when "10000", --a
"0000000" when "10001", --
"1101111" when "10010", --o
"1101001" when "10011", --i
"1110100" when "10100", --t
"1100001" when "10101", --a
"1110110" when "10110", --v
"1100001" when "10111", --a
"0000000" when "11000", --
"1100001" when "11001", --a
"1100011" when "11010", --c
"1101001" when "11011", --i
"1101101" when "11100", --m
"1100001" when others; --a
--Texto "A -> Meio tom abaixo";
t_am_on <=
'1' when (pix_y(9 downto 4)=5) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=63) else
'0';
with pix_x(8 downto 3) select
char_addr_am <=
"1000001" when "101101", --A
"0000000" when "101110", --
"0011010" when "101111", -->
"0000000" when "110000", --
"1001101" when "110001", --M
"1100101" when "110010", --e
"1101001" when "110011", --i
"1101111" when "110100", --o
"0000000" when "110101", --
"1110100" when "110110", --t
"1101111" when "110111", --o
"1101101" when "111000", --m
"0000000" when "111001", --
"1100001" when "111010", --a
"1100010" when "111011", --b
167
"1100001" when "111100", --a
"1101001" when "111101", --i
"1111000" when "111110", --x
"1101111" when others; --o
--Texto "S -> Um tom abaixo";
t_sm_on <=
'1' when (pix_y(9 downto 4)=7) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=61) else
'0';
with pix_x(8 downto 3) select
char_addr_sm <=
"1010011" when "101101", --S
"0000000" when "101110", --
"0011010" when "101111", -->
"0000000" when "110000", --
"1010101" when "110001", --U
"1101101" when "110010", --m
"0000000" when "110011", --
"1110100" when "110100", --t
"1101111" when "110101", --o
"1101101" when "110110", --m
"0000000" when "110111", --
"1100001" when "111000", --a
"1100010" when "111001", --b
"1100001" when "111010", --a
"1101001" when "111011", --i
"1111000" when "111100", --x
"1101111" when others; --o
--Texto "D -> Um tom e meio abaixo";
t_dm_on <=
'1' when (pix_y(9 downto 4)=9) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=68) else
'0';
with pix_x(9 downto 3) select
char_addr_dm <=
"1000100" when "0101101", --D
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010101" when "0110001", --U
"1101101" when "0110010", --m
"0000000" when "0110011", --
"1110100" when "0110100", --t
"1101111" when "0110101", --o
"1101101" when "0110110", --m
"0000000" when "0110111", --
"1100101" when "0111000", --e
"0000000" when "0111001", --
"1101101" when "0111010", --m
"1100101" when "0111011", --e
"1101001" when "0111100", --i
"1101111" when "0111101", --o
"0000000" when "0111110", --
"1100001" when "0111111", --a
"1100010" when "1000000", --b
"1100001" when "1000001", --a
"1101001" when "1000010", --i
"1111000" when "1000011", --x
"1101111" when others; --o
--Texto "F -> Dois tons abaixo";
t_fm_on <=
'1' when (pix_y(9 downto 4)=11) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=64) else
168
'0';
with pix_x(9 downto 3) select
char_addr_fm <=
"1000110" when "0101101", --F
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1000100" when "0110001", --D
"1101111" when "0110010", --o
"1101001" when "0110011", --i
"1110011" when "0110100", --s
"0000000" when "0110101", --
"1110100" when "0110110", --t
"1101111" when "0110111", --o
"1101110" when "0111000", --n
"1110011" when "0111001", --s
"0000000" when "0111010", --
"1100001" when "0111011", --a
"1100010" when "0111100", --b
"1100001" when "0111101", --a
"1101001" when "0111110", --i
"1111000" when "0111111", --x
"1101111" when others; --o
--Texto "G -> Dois tons e meio abaixo";
t_gm_on <=
'1' when (pix_y(9 downto 4)=13) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=71) else
'0';
with pix_x(9 downto 3) select
char_addr_gm <=
"1000111" when "0101101", --G
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1000100" when "0110001", --D
"1101111" when "0110010", --o
"1101001" when "0110011", --i
"1110011" when "0110100", --s
"0000000" when "0110101", --
"1110100" when "0110110", --t
"1101111" when "0110111", --o
"1101110" when "0111000", --n
"1110011" when "0111001", --s
"0000000" when "0111010", --
"1100101" when "0111011", --e
"0000000" when "0111100", --
"1101101" when "0111101", --m
"1100101" when "0111110", --e
"1101001" when "0111111", --i
"1101111" when "1000000", --o
"0000000" when "1000001", --
"1100001" when "1000010", --a
"1100010" when "1000011", --b
"1100001" when "1000100", --a
"1101001" when "1000101", --i
"1111000" when "1000110", --x
"1101111" when others; --o
--Texto "H -> Três tons abaixo";
t_hm_on <=
'1' when (pix_y(9 downto 4)=15) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=64) else
'0';
169
with pix_x(9 downto 3) select
char_addr_hm <=
"1001000" when "0101101", --H
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1110010" when "0110010", --r
"0000100" when "0110011", --ê
"1110011" when "0110100", --s
"0000000" when "0110101", --
"1110100" when "0110110", --t
"1101111" when "0110111", --o
"1101110" when "0111000", --n
"1110011" when "0111001", --s
"0000000" when "0111010", --
"1100001" when "0111011", --a
"1100010" when "0111100", --b
"1100001" when "0111101", --a
"1101001" when "0111110", --i
"1111000" when "0111111", --x
"1101111" when others; --o
--Texto "J -> Três tons e meio abaixo";
t_jm_on <=
'1' when (pix_y(9 downto 4)=17) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=71) else
'0';
with pix_x(9 downto 3) select
char_addr_jm <=
"1001010" when "0101101", --J
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1110010" when "0110010", --r
"0000100" when "0110011", --ê
"1110011" when "0110100", --s
"0000000" when "0110101", --
"1110100" when "0110110", --t
"1101111" when "0110111", --o
"1101110" when "0111000", --n
"1110011" when "0111001", --s
"0000000" when "0111010", --
"1100101" when "0111011", --e
"0000000" when "0111100", --
"1101101" when "0111101", --m
"1100101" when "0111110", --e
"1101001" when "0111111", --i
"1101111" when "1000000", --o
"0000000" when "1000001", --
"1100001" when "1000010", --a
"1100010" when "1000011", --b
"1100001" when "1000100", --a
"1101001" when "1000101", --i
"1111000" when "1000110", --x
"1101111" when others; --o
--Texto "K -> Quatro tons abaixo";
t_km_on <=
'1' when (pix_y(9 downto 4)=19) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=66) else
'0';
with pix_x(9 downto 3) select
170
char_addr_km <=
"1001011" when "0101101", --K
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010001" when "0110001", --Q
"1110101" when "0110010", --u
"1100001" when "0110011", --a
"1110100" when "0110100", --t
"1110010" when "0110101", --r
"1101111" when "0110110", --o
"0000000" when "0110111", --
"1110100" when "0111000", --t
"1101111" when "0111001", --o
"1101110" when "0111010", --n
"1110011" when "0111011", --s
"0000000" when "0111100", --
"1100001" when "0111101", --a
"1100010" when "0111110", --b
"1100001" when "0111111", --a
"1101001" when "1000000", --i
"1111000" when "1000001", --x
"1101111" when others; --o
--Texto "L -> Quatro tons e meio abaixo";
t_lm_on <=
'1' when (pix_y(9 downto 4)=21) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=73) else
'0';
with pix_x(9 downto 3) select
char_addr_lm <=
"1001100" when "0101101", --L
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010001" when "0110001", --Q
"1110101" when "0110010", --u
"1100001" when "0110011", --a
"1110100" when "0110100", --t
"1110010" when "0110101", --r
"1101111" when "0110110", --o
"0000000" when "0110111", --
"1110100" when "0111000", --t
"1101111" when "0111001", --o
"1101110" when "0111010", --n
"1110011" when "0111011", --s
"0000000" when "0111100", --
"1100101" when "0111101", --e
"0000000" when "0111110", --
"1101101" when "0111111", --m
"1100101" when "1000000", --e
"1101001" when "1000001", --i
"1101111" when "1000010", --o
"0000000" when "1000011", --
"1100001" when "1000100", --a
"1100010" when "1000101", --b
"1100001" when "1000110", --a
"1101001" when "1000111", --i
"1111000" when "1001000", --x
"1101111" when others; --o
--Texto "ç -> Cinco tons abaixo";
t_3m_on <=
171
'1' when (pix_y(9 downto 4)=23) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=65) else
'0';
with pix_x(9 downto 3) select
char_addr_3m <=
"0000010" when "0101101", --ç
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1000011" when "0110001", --C
"1101001" when "0110010", --i
"1101110" when "0110011", --n
"1100011" when "0110100", --c
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1110100" when "0110111", --t
"1101111" when "0111000", --o
"1101110" when "0111001", --n
"1110011" when "0111010", --s
"0000000" when "0111011", --
"1100001" when "0111100", --a
"1100010" when "0111101", --b
"1100001" when "0111110", --a
"1101001" when "0111111", --i
"1111000" when "1000000", --x
"1101111" when others; --o
--Texto "~ -> Cinco tons e meio abaixo";
t_4m_on <=
'1' when (pix_y(9 downto 4)=25) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=72) else
'0';
with pix_x(9 downto 3) select
char_addr_4m <=
"1111110" when "0101101", --~
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1000011" when "0110001", --C
"1101001" when "0110010", --i
"1101110" when "0110011", --n
"1100011" when "0110100", --c
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1110100" when "0110111", --t
"1101111" when "0111000", --o
"1101110" when "0111001", --n
"1110011" when "0111010", --s
"0000000" when "0111011", --
"1100101" when "0111100", --e
"0000000" when "0111101", --
"1101101" when "0111110", --m
"1100101" when "0111111", --e
"1101001" when "1000000", --i
"1101111" when "1000001", --o
"0000000" when "1000010", --
"1100001" when "1000011", --a
"1100010" when "1000100", --b
"1100001" when "1000101", --a
"1101001" when "1000110", --i
"1111000" when "1000111", --x
"1101111" when others; --o
--Texto "] -> Uma oitava abaixo";
172
t_5m_on <=
'1' when (pix_y(9 downto 4)=27) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=65) else
'0';
with pix_x(9 downto 3) select
char_addr_5m <=
"1011101" when "0101101", --[
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010101" when "0110001", --U
"1101101" when "0110010", --m
"1100001" when "0110011", --a
"0000000" when "0110100", --
"1101111" when "0110101", --o
"1101001" when "0110110", --i
"1110100" when "0110111", --t
"1100001" when "0111000", --a
"1110110" when "0111001", --v
"1100001" when "0111010", --a
"0000000" when "0111011", --
"1100001" when "0111100", --a
"1100010" when "0111101", --b
"1100001" when "0111110", --a
"1101001" when "0111111", --i
"1111000" when "1000000", --x
"1101111" when others; --o
--Texto "Enter -> Tom original";
t_enterm_on <=
'1' when (pix_y(9 downto 4)=29) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=29) else
'0';
with pix_x(7 downto 3) select
char_addr_enterm <=
"1000101" when "01010", --E
"1101110" when "01011", --n
"1110100" when "01100", --t
"1100101" when "01101", --e
"1110010" when "01110", --r
"0000000" when "01111", --
"0011010" when "10000", -->
"0000000" when "10001", --
"1010100" when "10010", --T
"1101111" when "10011", --o
"1101101" when "10100", --m
"0000000" when "10101", --
"1101111" when "10110", --o
"1110010" when "10111", --r
"1101001" when "11000", --i
"1100111" when "11001", --g
"1101001" when "11010", --i
"1101110" when "11011", --n
"1100001" when "11100", --a
"1101100" when others; --l
--Texto "Esc -> Menu"
t_escm_on <=
'1' when (pix_y(9 downto 4)=29) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=54) else
'0';
with pix_x(8 downto 3) select
char_addr_escm <=
"1000101" when "101101", --E
"1110011" when "101110", --s
173
"1100011" when "101111", --c
"0000000" when "110000", --
"0011010" when "110001", -->
"0000000" when "110010", --
"1001101" when "110011", --M
"1100101" when "110100", --e
"1101110" when "110101", --n
"1110101" when others; --u
--Texto "Q -> Tempo original * 7/8";
t_qt_on <=
'1' when (pix_y(9 downto 4)=7) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=33) else
'0';
with pix_x(8 downto 3) select
char_addr_qt <=
"1010001" when "001010", --Q
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110111" when "011111", --7
"0101111" when "100000", --/
"0111000" when others; --8
--Texto "W -> Tempo original * 6/8";
t_wt_on <=
'1' when (pix_y(9 downto 4)=9) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=33) else
'0';
with pix_x(8 downto 3) select
char_addr_wt <=
"1010111" when "001010", --W
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
174
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110110" when "011111", --6
"0101111" when "100000", --/
"0111000" when others; --8
--Texto "E -> Tempo original * 5/8";
t_et_on <=
'1' when (pix_y(9 downto 4)=11) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=33) else
'0';
with pix_x(8 downto 3) select
char_addr_et <=
"1000101" when "001010", --E
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110101" when "011111", --5
"0101111" when "100000", --/
"0111000" when others; --8
--Texto "R -> Tempo original * 1/2";
t_rt_on <=
'1' when (pix_y(9 downto 4)=13) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=33) else
'0';
with pix_x(8 downto 3) select
char_addr_rt <=
"1010010" when "001010", --R
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
175
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110001" when "011111", --1
"0101111" when "100000", --/
"0110010" when others; --2
--Texto "T -> Tempo original * 7/16";
t_tt_on <=
'1' when (pix_y(9 downto 4)=15) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=34) else
'0';
with pix_x(8 downto 3) select
char_addr_tt <=
"1010100" when "001010", --T
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110111" when "011111", --7
"0101111" when "100000", --/
"0110001" when "100001", --1
"0110110" when others; --6
--Texto "Y -> Tempo original * 6/16";
t_yt_on <=
'1' when (pix_y(9 downto 4)=17) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=34) else
'0';
with pix_x(8 downto 3) select
char_addr_yt <=
"1011001" when "001010", --Y
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
176
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110110" when "011111", --6
"0101111" when "100000", --/
"0110001" when "100001", --1
"0110110" when others; --6
--Texto "U -> Tempo original * 5/16";
t_ut_on <=
'1' when (pix_y(9 downto 4)=19) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=34) else
'0';
with pix_x(8 downto 3) select
char_addr_ut <=
"1010101" when "001010", --U
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110101" when "011111", --5
"0101111" when "100000", --/
"0110001" when "100001", --1
"0110110" when others; --6
--Texto "I -> Tempo original * 1/4";
t_it_on <=
'1' when (pix_y(9 downto 4)=21) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=33) else
'0';
with pix_x(8 downto 3) select
char_addr_it <=
"1001001" when "001010", --I
"0000000" when "001011", --
"0011010" when "001100", -->
"0000000" when "001101", --
"1010100" when "001110", --T
"1100101" when "001111", --e
"1101101" when "010000", --m
"1110000" when "010001", --p
"1101111" when "010010", --o
"0000000" when "010011", --
"1101111" when "010100", --o
"1110010" when "010101", --r
"1101001" when "010110", --i
177
"1100111" when "010111", --g
"1101001" when "011000", --i
"1101110" when "011001", --n
"1100001" when "011010", --a
"1101100" when "011011", --l
"0000000" when "011100", --
"0101010" when "011101", --*
"0000000" when "011110", --
"0110001" when "011111", --1
"0101111" when "100000", --/
"0110100" when others; --4
--Texto "A -> Tempo original * 5/4";
t_at_on <=
'1' when (pix_y(9 downto 4)=7) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=68) else
'0';
with pix_x(9 downto 3) select
char_addr_at <=
"1000001" when "0101101", --A
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110101" when "1000010", --5
"0101111" when "1000011", --/
"0110100" when others; --4
--Texto "S -> Tempo original * 6/4";
t_st_on <=
'1' when (pix_y(9 downto 4)=9) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=68) else
'0';
with pix_x(9 downto 3) select
char_addr_st <=
"1010011" when "0101101", --S
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
178
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110110" when "1000010", --6
"0101111" when "1000011", --/
"0110100" when others; --4
--Texto "D -> Tempo original * 7/4";
t_dt_on <=
'1' when (pix_y(9 downto 4)=11) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=68) else
'0';
with pix_x(9 downto 3) select
char_addr_dt <=
"1000100" when "0101101", --D
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110111" when "1000010", --7
"0101111" when "1000011", --/
"0110100" when others; --4
--Texto "F -> Tempo original * 2";
t_ft_on <=
'1' when (pix_y(9 downto 4)=13) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=66) else
'0';
with pix_x(9 downto 3) select
char_addr_ft <=
"1000110" when "0101101", --F
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
179
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110010" when others; --2
--Texto "G -> Tempo original * 9/4";
t_gt_on <=
'1' when (pix_y(9 downto 4)=15) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=68) else
'0';
with pix_x(9 downto 3) select
char_addr_gt <=
"1000111" when "0101101", --G
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0111001" when "1000010", --9
"0101111" when "1000011", --/
"0110100" when others; --4
--Texto "H -> Tempo original * 10/4";
t_ht_on <=
'1' when (pix_y(9 downto 4)=17) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=69) else
'0';
with pix_x(9 downto 3) select
char_addr_ht <=
"1001000" when "0101101", --H
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
"1100111" when "0111010", --g
"1101001" when "0111011", --i
180
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110001" when "1000010", --1
"0110000" when "1000011", --0
"0101111" when "1000100", --/
"0110100" when others; --4
--Texto "J -> Tempo original * 11/4";
t_jt_on <=
'1' when (pix_y(9 downto 4)=19) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=69) else
'0';
with pix_x(9 downto 3) select
char_addr_jt <=
"1001010" when "0101101", --J
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110001" when "1000010", --1
"0110001" when "1000011", --1
"0101111" when "1000100", --/
"0110100" when others; --4
--Texto "K -> Tempo original * 3";
t_kt_on <=
'1' when (pix_y(9 downto 4)=21) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=66) else
'0';
with pix_x(9 downto 3) select
char_addr_kt <=
"1001011" when "0101101", --J
"0000000" when "0101110", --
"0011010" when "0101111", -->
"0000000" when "0110000", --
"1010100" when "0110001", --T
"1100101" when "0110010", --e
"1101101" when "0110011", --m
"1110000" when "0110100", --p
"1101111" when "0110101", --o
"0000000" when "0110110", --
"1101111" when "0110111", --o
"1110010" when "0111000", --r
"1101001" when "0111001", --i
181
"1100111" when "0111010", --g
"1101001" when "0111011", --i
"1101110" when "0111100", --n
"1100001" when "0111101", --a
"1101100" when "0111110", --l
"0000000" when "0111111", --
"0101010" when "1000000", --*
"0000000" when "1000001", --
"0110011" when others; --3
--Texto "Enter -> Tempo original";
t_entert_on <=
'1' when (pix_y(9 downto 4)=23) and (10<=pix_x(9 downto 3) and pix_x(9 downto 3)<=31) else
'0';
with pix_x(7 downto 3) select
char_addr_entert <=
"1000101" when "01010", --E
"1101110" when "01011", --n
"1110100" when "01100", --t
"1100101" when "01101", --e
"1110010" when "01110", --r
"0000000" when "01111", --
"0011010" when "10000", -->
"0000000" when "10001", --
"1010100" when "10010", --T
"1100101" when "10011", --e
"1101101" when "10100", --m
"1110000" when "10101", --p
"1101111" when "10110", --o
"0000000" when "10111", --
"1101111" when "11000", --o
"1110010" when "11001", --r
"1101001" when "11010", --i
"1100111" when "11011", --g
"1101001" when "11100", --i
"1101110" when "11101", --n
"1100001" when "11110", --a
"1101100" when others; --l
--Texto "Esc -> Menu"
t_esct_on <=
'1' when (pix_y(9 downto 4)=23) and (45<=pix_x(9 downto 3) and pix_x(9 downto 3)<=54) else
'0';
with pix_x(8 downto 3) select
char_addr_esct <=
"1000101" when "101101", --E
"1110011" when "101110", --s
"1100011" when "101111", --c
"0000000" when "110000", --
"0011010" when "110001", -->
"0000000" when "110010", --
"1001101" when "110011", --M
"1100101" when "110100", --e
"1101110" when "110101", --n
"1110101" when others; --u
--Interface Font Rom
rom_addr <= char_addr & row_addr;
font_bit <= font_word(to_integer(unsigned(not bit_addr)));
row_addr_8x16 <= std_logic_vector(pix_y(3 downto 0));
bit_addr_8x16 <= std_logic_vector(pix_x(2 downto 0));
row_addr_16x32 <= std_logic_vector(pix_y(4 downto 1));
bit_addr_16x32 <= std_logic_vector(pix_x(3 downto 1));
182
textyellow_rgb <= "00110111";
textorange_rgb <= "00011111";
--Mux RGB
process(video_on,tecladob1_on,tecladob2_on,tecladob3_on,tecladob4_on,tecladob5_on,tecladob6_on,tec
ladob7_on,tecladob_rgb,tecladop1_on,tecladop2_on,tecladop3_on,tecladop4_on,tecladop5_on,tecladop_rgb,
divisao1_on,divisao2_on,divisao3_on,divisao4_on,divisao5_on,divisao6_on,divisao_rgb,marcab11_on,marcab1
2_on,marcab13_on,marcab14_on,marcab15_on,
marcab21_on,marcab22_on,marcab23_on,marcab24_on,marcab25_on,marcab31_on,marcab32_on,marcab33_on
,marcab34_on,marcab35_on,marcab41_on,marcab42_on,marcab43_on,marcab44_on,marcab45_on,
marcab51_on,marcab52_on,marcab53_on,marcab54_on,marcab55_on,marcab61_on,marcab62_on,marcab63_on
,marcab64_on,marcab65_on,marcab71_on,marcab72_on,marcab73_on,marcab74_on,marcab75_on,
marcabon_rgb,marcaboff_rgb,marcap11_on,marcap12_on,marcap13_on,marcap14_on,marcap15_on,marcap21_
on,marcap22_on,marcap23_on,marcap24_on,marcap25_on,marcap31_on,marcap32_on,marcap33_on,marcap34
_on,marcap35_on,
marcap41_on,marcap42_on,marcap43_on,marcap44_on,marcap45_on,marcap51_on,marcap52_on,marcap53_on
,marcap54_on,marcap55_on,marcapon_rgb,marcapoff_rgb,nota1_mod,nota2_mod,nota3_mod,nota4_mod,nota5
_mod,
t_livre_on,t_gravacao_on,t_leitura_on,t_esc_on,char_addr_livre,char_addr_gravacao,char_addr_leitura,char_add
r_esc,row_addr_16x32,bit_addr_16x32,row_addr_8x16,bit_addr_8x16,font_bit,textyellow_rgb,textorange_rgb,
t_menu_on,t_f1_on,t_f2_on,t_f3_on,t_f4_on,t_memg_on,t_1_on,t_2_on,t_3_on,char_addr_menu,char_addr_f1,c
har_addr_f2,char_addr_f3,char_addr_f4,char_addr_memg,char_addr_1,char_addr_2,char_addr_3,
t_memf_on,char_addr_memf,t_meml_on,char_addr_meml,t_mema_on,char_addr_mema,t_memm_on,t_memt_o
n,char_addr_memm,char_addr_memt,t_qm_on,char_addr_qm,t_am_on,char_addr_am,
t_wm_on,t_em_on,char_addr_wm,char_addr_em,t_rm_on,t_tm_on,char_addr_rm,char_addr_tm,t_ym_on,t_um_
on,t_im_on,t_om_on,t_pm_on,t_1m_on,t_2m_on,char_addr_ym,char_addr_um,char_addr_im,char_addr_om,cha
r_addr_pm,char_addr_1m,char_addr_2m,
t_sm_on,char_addr_sm,t_dm_on,char_addr_dm,t_fm_on,char_addr_fm,t_gm_on,char_addr_gm,t_hm_on,char_a
ddr_hm,t_jm_on,char_addr_jm,t_km_on,char_addr_km,t_lm_on,char_addr_lm,t_3m_on,char_addr_3m,t_4m_on
,char_addr_4m,t_5m_on,char_addr_5m,
t_enterm_on,t_escm_on,char_addr_enterm,char_addr_escm,t_qt_on,t_wt_on,t_et_on,t_rt_on,t_tt_on,t_yt_on,t_u
t_on,t_it_on,t_at_on,t_st_on,t_dt_on,t_ft_on,t_gt_on,t_ht_on,t_jt_on,t_kt_on,t_entert_on,t_esct_on,
char_addr_qt,char_addr_wt,char_addr_et,char_addr_rt,char_addr_tt,char_addr_yt,char_addr_ut,char_addr_it,cha
r_addr_at,char_addr_st,char_addr_dt,char_addr_ft,char_addr_gt,char_addr_ht,char_addr_jt,char_addr_kt,char_a
ddr_entert,char_addr_esct,
estado)
begin
char_addr <= "0000000";
row_addr <= "0000";
bit_addr <= "000";
if video_on='0' then
graph_rgb <= "00000000";
else
if estado="0000" and t_menu_on='1' then
char_addr <= char_addr_menu;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
183
else
graph_rgb <= "01000000";
end if;
elsif estado="0000" and t_f1_on='1' then
char_addr <= char_addr_f1;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0000" and t_f2_on='1' then
char_addr <= char_addr_f2;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0000" and t_f3_on='1' then
char_addr <= char_addr_f3;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0000" and t_f4_on='1' then
char_addr <= char_addr_f4;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0001" and t_livre_on='1' then
char_addr <= char_addr_livre;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0010" and t_memg_on='1' then
char_addr <= char_addr_memg;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif (estado="0010" or estado="0101") and t_1_on='1' then
char_addr <= char_addr_1;
row_addr <= row_addr_8x16;
184
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif (estado="0010" or estado="0101") and t_2_on='1' then
char_addr <= char_addr_2;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif (estado="0010" or estado="0101") and t_3_on='1' then
char_addr <= char_addr_3;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif (estado="0001" or estado="0011" or estado="1000" or estado="0010" or
estado="0101" or estado="0100") and t_esc_on='1' then
char_addr <= char_addr_esc;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0011" and t_gravacao_on='1' then
char_addr <= char_addr_gravacao;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0100" and t_memf_on='1' then
char_addr <= char_addr_memf;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0101" and t_meml_on='1' then
char_addr <= char_addr_meml;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
185
end if;
elsif estado="0110" and t_memm_on='1' then
char_addr <= char_addr_memm;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_memt_on='1' then
char_addr <= char_addr_memt;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="1000" and t_leitura_on='1' then
char_addr <= char_addr_leitura;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="1001" and t_mema_on='1' then
char_addr <= char_addr_mema;
row_addr <= row_addr_16x32;
bit_addr <= bit_addr_16x32;
if font_bit='1' then
graph_rgb <= textyellow_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_qm_on='1' then
char_addr <= char_addr_qm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_am_on='1' then
char_addr <= char_addr_am;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_wm_on='1' then
char_addr <= char_addr_wm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
186
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_em_on='1' then
char_addr <= char_addr_em;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_rm_on='1' then
char_addr <= char_addr_rm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_tm_on='1' then
char_addr <= char_addr_tm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_ym_on='1' then
char_addr <= char_addr_ym;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_um_on='1' then
char_addr <= char_addr_um;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_im_on='1' then
char_addr <= char_addr_im;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_om_on='1' then
char_addr <= char_addr_om;
187
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_pm_on='1' then
char_addr <= char_addr_pm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_1m_on='1' then
char_addr <= char_addr_1m;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_2m_on='1' then
char_addr <= char_addr_2m;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_sm_on='1' then
char_addr <= char_addr_sm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_dm_on='1' then
char_addr <= char_addr_dm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_fm_on='1' then
char_addr <= char_addr_fm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
188
end if;
elsif estado="0110" and t_gm_on='1' then
char_addr <= char_addr_gm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_hm_on='1' then
char_addr <= char_addr_hm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_jm_on='1' then
char_addr <= char_addr_jm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_km_on='1' then
char_addr <= char_addr_km;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_lm_on='1' then
char_addr <= char_addr_lm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_3m_on='1' then
char_addr <= char_addr_3m;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_4m_on='1' then
char_addr <= char_addr_4m;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
189
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_5m_on='1' then
char_addr <= char_addr_5m;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_enterm_on='1' then
char_addr <= char_addr_enterm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0110" and t_escm_on='1' then
char_addr <= char_addr_escm;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_qt_on='1' then
char_addr <= char_addr_qt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_wt_on='1' then
char_addr <= char_addr_wt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_et_on='1' then
char_addr <= char_addr_et;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_rt_on='1' then
char_addr <= char_addr_rt;
190
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_tt_on='1' then
char_addr <= char_addr_tt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_yt_on='1' then
char_addr <= char_addr_yt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_ut_on='1' then
char_addr <= char_addr_ut;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_it_on='1' then
char_addr <= char_addr_it;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_at_on='1' then
char_addr <= char_addr_at;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_st_on='1' then
char_addr <= char_addr_st;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
191
end if;
elsif estado="0111" and t_dt_on='1' then
char_addr <= char_addr_dt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_ft_on='1' then
char_addr <= char_addr_ft;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_gt_on='1' then
char_addr <= char_addr_gt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_ht_on='1' then
char_addr <= char_addr_ht;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_jt_on='1' then
char_addr <= char_addr_jt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_kt_on='1' then
char_addr <= char_addr_kt;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_entert_on='1' then
char_addr <= char_addr_entert;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
192
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0111" and t_esct_on='1' then
char_addr <= char_addr_esct;
row_addr <= row_addr_8x16;
bit_addr <= bit_addr_8x16;
if font_bit='1' then
graph_rgb <= textorange_rgb;
else
graph_rgb <= "01000000";
end if;
elsif estado="0001" or estado="0011" or estado="1000" then
if marcab11_on='1' then
if nota1_mod="000000" or nota2_mod="000000" or nota3_mod="000000"
or nota4_mod="000000" or nota5_mod="000000" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap11_on='1' then
if nota1_mod="000001" or nota2_mod="000001" or nota3_mod="000001"
or nota4_mod="000001" or nota5_mod="000001" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab21_on='1' then
if nota1_mod="000010" or nota2_mod="000010" or nota3_mod="000010"
or nota4_mod="000010" or nota5_mod="000010" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap21_on='1' then
if nota1_mod="000011" or nota2_mod="000011" or nota3_mod="000011"
or nota4_mod="000011" or nota5_mod="000011" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab31_on='1' then
if nota1_mod="000100" or nota2_mod="000100" or nota3_mod="000100"
or nota4_mod="000100" or nota5_mod="000100" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab41_on='1' then
if nota1_mod="000101" or nota2_mod="000101" or nota3_mod="000101"
or nota4_mod="000101" or nota5_mod="000101" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap31_on='1' then
if nota1_mod="000110" or nota2_mod="000110" or nota3_mod="000110"
or nota4_mod="000110" or nota5_mod="000110" then
graph_rgb <= marcapon_rgb;
193
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab51_on='1' then
if nota1_mod="000111" or nota2_mod="000111" or nota3_mod="000111"
or nota4_mod="000111" or nota5_mod="000111" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap41_on='1' then
if nota1_mod="001000" or nota2_mod="001000" or nota3_mod="001000"
or nota4_mod="001000" or nota5_mod="001000" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab61_on='1' then
if nota1_mod="001001" or nota2_mod="001001" or nota3_mod="001001"
or nota4_mod="001001" or nota5_mod="001001" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap51_on='1' then
if nota1_mod="001010" or nota2_mod="001010" or nota3_mod="001010"
or nota4_mod="001010" or nota5_mod="001010" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab71_on='1' then
if nota1_mod="001011" or nota2_mod="001011" or nota3_mod="001011"
or nota4_mod="001011" or nota5_mod="001011" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab12_on='1' then
if nota1_mod="001100" or nota2_mod="001100" or nota3_mod="001100"
or nota4_mod="001100" or nota5_mod="001100" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap12_on='1' then
if nota1_mod="001101" or nota2_mod="001101" or nota3_mod="001101"
or nota4_mod="001101" or nota5_mod="001101" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab22_on='1' then
if nota1_mod="001110" or nota2_mod="001110" or nota3_mod="001110"
or nota4_mod="001110" or nota5_mod="001110" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap22_on='1' then
194
if nota1_mod="001111" or nota2_mod="001111" or nota3_mod="001111"
or nota4_mod="001111" or nota5_mod="001111" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab32_on='1' then
if nota1_mod="010000" or nota2_mod="010000" or nota3_mod="010000"
or nota4_mod="010000" or nota5_mod="010000" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab42_on='1' then
if nota1_mod="010001" or nota2_mod="010001" or nota3_mod="010001"
or nota4_mod="010001" or nota5_mod="010001" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap32_on='1' then
if nota1_mod="010010" or nota2_mod="010010" or nota3_mod="010010"
or nota4_mod="010010" or nota5_mod="010010" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab52_on='1' then
if nota1_mod="010011" or nota2_mod="010011" or nota3_mod="010011"
or nota4_mod="010011" or nota5_mod="010011" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap42_on='1' then
if nota1_mod="010100" or nota2_mod="010100" or nota3_mod="010100"
or nota4_mod="010100" or nota5_mod="010100" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab62_on='1' then
if nota1_mod="010101" or nota2_mod="010101" or nota3_mod="010101"
or nota4_mod="010101" or nota5_mod="010101" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap52_on='1' then
if nota1_mod="010110" or nota2_mod="010110" or nota3_mod="010110"
or nota4_mod="010110" or nota5_mod="010110" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab72_on='1' then
if nota1_mod="010111" or nota2_mod="010111" or nota3_mod="010111"
or nota4_mod="010111" or nota5_mod="010111" then
graph_rgb <= marcabon_rgb;
else
195
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab13_on='1' then
if nota1_mod="011000" or nota2_mod="011000" or nota3_mod="011000"
or nota4_mod="011000" or nota5_mod="011000" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap13_on='1' then
if nota1_mod="011001" or nota2_mod="011001" or nota3_mod="011001"
or nota4_mod="011001" or nota5_mod="011001" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab23_on='1' then
if nota1_mod="011010" or nota2_mod="011010" or nota3_mod="011010"
or nota4_mod="011010" or nota5_mod="011010" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap23_on='1' then
if nota1_mod="011011" or nota2_mod="011011" or nota3_mod="011011"
or nota4_mod="011011" or nota5_mod="011011" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab33_on='1' then
if nota1_mod="011100" or nota2_mod="011100" or nota3_mod="011100"
or nota4_mod="011100" or nota5_mod="011100" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab43_on='1' then
if nota1_mod="011101" or nota2_mod="011101" or nota3_mod="011101"
or nota4_mod="011101" or nota5_mod="011101" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap33_on='1' then
if nota1_mod="011110" or nota2_mod="011110" or nota3_mod="011110"
or nota4_mod="011110" or nota5_mod="011110" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab53_on='1' then
if nota1_mod="011111" or nota2_mod="011111" or nota3_mod="011111"
or nota4_mod="011111" or nota5_mod="011111" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap43_on='1' then
196
if nota1_mod="100000" or nota2_mod="100000" or nota3_mod="100000"
or nota4_mod="100000" or nota5_mod="100000" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab63_on='1' then
if nota1_mod="100001" or nota2_mod="100001" or nota3_mod="100001"
or nota4_mod="100001" or nota5_mod="100001" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap53_on='1' then
if nota1_mod="100010" or nota2_mod="100010" or nota3_mod="100010"
or nota4_mod="100010" or nota5_mod="100010" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab73_on='1' then
if nota1_mod="100011" or nota2_mod="100011" or nota3_mod="100011"
or nota4_mod="100011" or nota5_mod="100011" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab14_on='1' then
if nota1_mod="100100" or nota2_mod="100100" or nota3_mod="100100"
or nota4_mod="100100" or nota5_mod="100100" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap14_on='1' then
if nota1_mod="100101" or nota2_mod="100101" or nota3_mod="100101"
or nota4_mod="100101" or nota5_mod="100101" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab24_on='1' then
if nota1_mod="100110" or nota2_mod="100110" or nota3_mod="100110"
or nota4_mod="100110" or nota5_mod="100110" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap24_on='1' then
if nota1_mod="100111" or nota2_mod="100111" or nota3_mod="100111"
or nota4_mod="100111" or nota5_mod="100111" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab34_on='1' then
if nota1_mod="101000" or nota2_mod="101000" or nota3_mod="101000"
or nota4_mod="101000" or nota5_mod="101000" then
graph_rgb <= marcabon_rgb;
else
197
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab44_on='1' then
if nota1_mod="101001" or nota2_mod="101001" or nota3_mod="101001"
or nota4_mod="101001" or nota5_mod="101001" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap34_on='1' then
if nota1_mod="101010" or nota2_mod="101010" or nota3_mod="101010"
or nota4_mod="101010" or nota5_mod="101010" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab54_on='1' then
if nota1_mod="101011" or nota2_mod="101011" or nota3_mod="101011"
or nota4_mod="101011" or nota5_mod="101011" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap44_on='1' then
if nota1_mod="101100" or nota2_mod="101100" or nota3_mod="101100"
or nota4_mod="101100" or nota5_mod="101100" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab64_on='1' then
if nota1_mod="101101" or nota2_mod="101101" or nota3_mod="101101"
or nota4_mod="101101" or nota5_mod="101101" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap54_on='1' then
if nota1_mod="101110" or nota2_mod="101110" or nota3_mod="101110"
or nota4_mod="101110" or nota5_mod="101110" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab74_on='1' then
if nota1_mod="101111" or nota2_mod="101111" or nota3_mod="101111"
or nota4_mod="101111" or nota5_mod="101111" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab15_on='1' then
if nota1_mod="110000" or nota2_mod="110000" or nota3_mod="110000"
or nota4_mod="110000" or nota5_mod="110000" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap15_on='1' then
198
if nota1_mod="110001" or nota2_mod="110001" or nota3_mod="110001"
or nota4_mod="110001" or nota5_mod="110001" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab25_on='1' then
if nota1_mod="110010" or nota2_mod="110010" or nota3_mod="110010"
or nota4_mod="110010" or nota5_mod="110010" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap25_on='1' then
if nota1_mod="110011" or nota2_mod="110011" or nota3_mod="110011"
or nota4_mod="110011" or nota5_mod="110011" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab35_on='1' then
if nota1_mod="110100" or nota2_mod="110100" or nota3_mod="110100"
or nota4_mod="110100" or nota5_mod="110100" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcab45_on='1' then
if nota1_mod="110101" or nota2_mod="110101" or nota3_mod="110101"
or nota4_mod="110101" or nota5_mod="110101" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap35_on='1' then
if nota1_mod="110110" or nota2_mod="110110" or nota3_mod="110110"
or nota4_mod="110110" or nota5_mod="110110" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab55_on='1' then
if nota1_mod="110111" or nota2_mod="110111" or nota3_mod="110111"
or nota4_mod="110111" or nota5_mod="110111" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap45_on='1' then
if nota1_mod="111000" or nota2_mod="111000" or nota3_mod="111000"
or nota4_mod="111000" or nota5_mod="111000" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab65_on='1' then
if nota1_mod="111001" or nota2_mod="111001" or nota3_mod="111001"
or nota4_mod="111001" or nota5_mod="111001" then
graph_rgb <= marcabon_rgb;
else
199
graph_rgb <= marcaboff_rgb;
end if;
elsif marcap55_on='1' then
if nota1_mod="111010" or nota2_mod="111010" or nota3_mod="111010"
or nota4_mod="111010" or nota5_mod="111010" then
graph_rgb <= marcapon_rgb;
else
graph_rgb <= marcapoff_rgb;
end if;
elsif marcab75_on='1' then
if nota1_mod="111011" or nota2_mod="111011" or nota3_mod="111011"
or nota4_mod="111011" or nota5_mod="111011" then
graph_rgb <= marcabon_rgb;
else
graph_rgb <= marcaboff_rgb;
end if;
elsif divisao1_on='1' or divisao2_on='1' or divisao3_on='1' or divisao4_on='1' or
divisao5_on='1' or divisao6_on='1' then
graph_rgb <= divisao_rgb;
elsif tecladop1_on='1' or tecladop2_on='1' or tecladop3_on='1' or tecladop4_on='1'
or tecladop5_on='1' then
graph_rgb <= tecladop_rgb;
elsif tecladob1_on='1' or tecladob2_on='1' or tecladob3_on='1' or tecladob4_on='1'
or tecladob5_on='1' or tecladob6_on='1' or tecladob7_on='1' then
graph_rgb <= tecladob_rgb;
else
graph_rgb <= "01000000";
end if;
else
graph_rgb <= "01000000";
end if;
end if;
end process;
end pixelgen_VGA;
200
Anexo J – Código em VHDL da ROM das fontes
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Font_rom is
Port ( clk: in std_logic;
addr: in std_logic_vector(10 downto 0);
data: out std_logic_vector(7 downto 0));
end Font_rom;
architecture font_rom of Font_rom is
constant ADDR_WIDTH: integer:=11;
constant DATA_WIDTH: integer:=8;
signal addr_reg: std_logic_vector(ADDR_WIDTH-1 downto 0);
type rom_type is array (0 to 2**ADDR_WIDTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
constant ROM: rom_type:=( -- 2^11-by-8
-- code x00
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x01
"00000000", -- 0
"00000000", -- 1
"01110110", -- 2 *** **
"11011100", -- 3 ** ***
"00000000", -- 4
"01111000", -- 5 ****
"00001100", -- 6 **
"01111100", -- 7 *****
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01110110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x02
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11000000", -- 7 **
"11000000", -- 8 **
"11000000", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00110000", -- c **
"00110000", -- d **
"01100000", -- e **
"00000000", -- f
-- code x03
"00000000", -- 0
"00000000", -- 1
"00001100", -- 2 **
"00011000", -- 3 **
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x04
"00010000", -- 0 *
"00111000", -- 1 ***
"01101100", -- 2 ** **
"11000110", -- 3 ** **
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11111110", -- 7 *******
"11000000", -- 8 **
"11000000", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x05
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00011000", -- 3 **
"00111100", -- 4 ****
"00111100", -- 5 ****
"11100111", -- 6 *** ***
"11100111", -- 7 *** ***
"11100111", -- 8 *** ***
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x06
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00011000", -- 3 **
"00111100", -- 4 ****
"01111110", -- 5 ******
"11111111", -- 6 ********
"11111111", -- 7 ********
"01111110", -- 8 ******
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x07
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"01101100", -- 4 ** **
"11111110", -- 5 *******
201
"11111110", -- 6 *******
"11111110", -- 7 *******
"11111110", -- 8 *******
"01111100", -- 9 *****
"00111000", -- a ***
"00010000", -- b *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x08
"11111111", -- 0 ********
"11111111", -- 1 ********
"11111111", -- 2 ********
"11111111", -- 3 ********
"11111111", -- 4 ********
"11111111", -- 5 ********
"11100111", -- 6 *** ***
"11000011", -- 7 ** **
"11000011", -- 8 ** **
"11100111", -- 9 *** ***
"11111111", -- a ********
"11111111", -- b ********
"11111111", -- c ********
"11111111", -- d ********
"11111111", -- e ********
"11111111", -- f ********
-- code x09
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00111100", -- 5 ****
"01100110", -- 6 ** **
"01000010", -- 7 * *
"01000010", -- 8 * *
"01100110", -- 9 ** **
"00111100", -- a ****
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x0a
"11111111", -- 0 ********
"11111111", -- 1 ********
"11111111", -- 2 ********
"11111111", -- 3 ********
"11111111", -- 4 ********
"11000011", -- 5 ** **
"10011001", -- 6 * ** *
"10111101", -- 7 * **** *
"10111101", -- 8 * **** *
"10011001", -- 9 * ** *
"11000011", -- a ** **
"11111111", -- b ********
"11111111", -- c ********
"11111111", -- d ********
"11111111", -- e ********
"11111111", -- f ********
-- code x0b
"00000000", -- 0
"00000000", -- 1
"00011110", -- 2 ****
"00001110", -- 3 ***
"00011010", -- 4 ** *
"00110010", -- 5 ** *
"01111000", -- 6 ****
"11001100", -- 7 ** **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01111000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x0c
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01100110", -- 6 ** **
"00111100", -- 7 ****
"00011000", -- 8 **
"01111110", -- 9 ******
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x0d
"00000000", -- 0
"00000000", -- 1
"00111111", -- 2 ******
"00110011", -- 3 ** **
"00111111", -- 4 ******
"00110000", -- 5 **
"00110000", -- 6 **
"00110000", -- 7 **
"00110000", -- 8 **
"01110000", -- 9 ***
"11110000", -- a ****
"11100000", -- b ***
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x0e
"00000000", -- 0
"00000000", -- 1
"01111111", -- 2 *******
"01100011", -- 3 ** **
"01111111", -- 4 *******
"01100011", -- 5 ** **
"01100011", -- 6 ** **
"01100011", -- 7 ** **
"01100011", -- 8 ** **
"01100111", -- 9 ** ***
"11100111", -- a *** ***
"11100110", -- b *** **
"11000000", -- c **
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x0f
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00011000", -- 3 **
"00011000", -- 4 **
"11011011", -- 5 ** ** **
"00111100", -- 6 ****
"11100111", -- 7 *** ***
"00111100", -- 8 ****
"11011011", -- 9 ** ** **
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x10
"00000000", -- 0
"10000000", -- 1 *
"11000000", -- 2 **
"11100000", -- 3 ***
"11110000", -- 4 ****
"11111000", -- 5 *****
"11111110", -- 6 *******
"11111000", -- 7 *****
"11110000", -- 8 ****
"11100000", -- 9 ***
"11000000", -- a **
"10000000", -- b *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x11
"00000000", -- 0
"00000010", -- 1 *
"00000110", -- 2 **
"00001110", -- 3 ***
"00011110", -- 4 ****
"00111110", -- 5 *****
"11111110", -- 6 *******
"00111110", -- 7 *****
"00011110", -- 8 ****
"00001110", -- 9 ***
"00000110", -- a **
"00000010", -- b *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
202
-- code x12
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00111100", -- 3 ****
"01111110", -- 4 ******
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"01111110", -- 8 ******
"00111100", -- 9 ****
"00011000", -- a **
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x13
"00000000", -- 0
"00000000", -- 1
"01100110", -- 2 ** **
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01100110", -- 6 ** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"00000000", -- 9
"01100110", -- a ** **
"01100110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x14
"00000000", -- 0
"00000000", -- 1
"01111111", -- 2 *******
"11011011", -- 3 ** ** **
"11011011", -- 4 ** ** **
"11011011", -- 5 ** ** **
"01111011", -- 6 **** **
"00011011", -- 7 ** **
"00011011", -- 8 ** **
"00011011", -- 9 ** **
"00011011", -- a ** **
"00011011", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x15
"00000000", -- 0
"01111100", -- 1 *****
"11000110", -- 2 ** **
"01100000", -- 3 **
"00111000", -- 4 ***
"01101100", -- 5 ** **
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"01101100", -- 8 ** **
"00111000", -- 9 ***
"00001100", -- a **
"11000110", -- b ** **
"01111100", -- c *****
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x16
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"11111110", -- 8 *******
"11111110", -- 9 *******
"11111110", -- a *******
"11111110", -- b *******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x17
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00111100", -- 3 ****
"01111110", -- 4 ******
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"01111110", -- 8 ******
"00111100", -- 9 ****
"00011000", -- a **
"01111110", -- b ******
"00110000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x18
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00111100", -- 3 ****
"01111110", -- 4 ******
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x19
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"01111110", -- 9 ******
"00111100", -- a ****
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1a
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00011000", -- 5 **
"00001100", -- 6 **
"11111110", -- 7 *******
"00001100", -- 8 **
"00011000", -- 9 **
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1b
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00110000", -- 5 **
"01100000", -- 6 **
"11111110", -- 7 *******
"01100000", -- 8 **
"00110000", -- 9 **
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1c
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"11000000", -- 6 **
"11000000", -- 7 **
"11000000", -- 8 **
203
"11111110", -- 9 *******
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1d
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00100100", -- 5 * *
"01100110", -- 6 ** **
"11111111", -- 7 ********
"01100110", -- 8 ** **
"00100100", -- 9 * *
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1e
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00010000", -- 4 *
"00111000", -- 5 ***
"00111000", -- 6 ***
"01111100", -- 7 *****
"01111100", -- 8 *****
"11111110", -- 9 *******
"11111110", -- a *******
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x1f
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"11111110", -- 4 *******
"11111110", -- 5 *******
"01111100", -- 6 *****
"01111100", -- 7 *****
"00111000", -- 8 ***
"00111000", -- 9 ***
"00010000", -- a *
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x20
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x21
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00111100", -- 3 ****
"00111100", -- 4 ****
"00111100", -- 5 ****
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00000000", -- 9
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x22
"00000000", -- 0
"01100110", -- 1 ** **
"01100110", -- 2 ** **
"01100110", -- 3 ** **
"00100100", -- 4 * *
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x23
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"01101100", -- 3 ** **
"01101100", -- 4 ** **
"11111110", -- 5 *******
"01101100", -- 6 ** **
"01101100", -- 7 ** **
"01101100", -- 8 ** **
"11111110", -- 9 *******
"01101100", -- a ** **
"01101100", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x24
"00011000", -- 0 **
"00011000", -- 1 **
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000010", -- 4 ** *
"11000000", -- 5 **
"01111100", -- 6 *****
"00000110", -- 7 **
"00000110", -- 8 **
"10000110", -- 9 * **
"11000110", -- a ** **
"01111100", -- b *****
"00011000", -- c **
"00011000", -- d **
"00000000", -- e
"00000000", -- f
-- code x25
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"11000010", -- 4 ** *
"11000110", -- 5 ** **
"00001100", -- 6 **
"00011000", -- 7 **
"00110000", -- 8 **
"01100000", -- 9 **
"11000110", -- a ** **
"10000110", -- b * **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x26
"00000000", -- 0
"00000000", -- 1
"00111000", -- 2 ***
"01101100", -- 3 ** **
"01101100", -- 4 ** **
"00111000", -- 5 ***
"01110110", -- 6 *** **
"11011100", -- 7 ** ***
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01110110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x27
"00000000", -- 0
"00110000", -- 1 **
204
"00110000", -- 2 **
"00110000", -- 3 **
"01100000", -- 4 **
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x28
"00000000", -- 0
"00000000", -- 1
"00001100", -- 2 **
"00011000", -- 3 **
"00110000", -- 4 **
"00110000", -- 5 **
"00110000", -- 6 **
"00110000", -- 7 **
"00110000", -- 8 **
"00110000", -- 9 **
"00011000", -- a **
"00001100", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x29
"00000000", -- 0
"00000000", -- 1
"00110000", -- 2 **
"00011000", -- 3 **
"00001100", -- 4 **
"00001100", -- 5 **
"00001100", -- 6 **
"00001100", -- 7 **
"00001100", -- 8 **
"00001100", -- 9 **
"00011000", -- a **
"00110000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2a
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01100110", -- 5 ** **
"00111100", -- 6 ****
"11111111", -- 7 ********
"00111100", -- 8 ****
"01100110", -- 9 ** **
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2b
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00011000", -- 5 **
"00011000", -- 6 **
"01111110", -- 7 ******
"00011000", -- 8 **
"00011000", -- 9 **
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2c
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00011000", -- 9 **
"00011000", -- a **
"00011000", -- b **
"00110000", -- c **
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2d
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"01111110", -- 7 ******
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2e
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x2f
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000010", -- 4 *
"00000110", -- 5 **
"00001100", -- 6 **
"00011000", -- 7 **
"00110000", -- 8 **
"01100000", -- 9 **
"11000000", -- a **
"10000000", -- b *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x30
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11001110", -- 5 ** ***
"11011110", -- 6 ** ****
"11110110", -- 7 **** **
"11100110", -- 8 *** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x31
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2
"00111000", -- 3
"01111000", -- 4 **
"00011000", -- 5 ***
"00011000", -- 6 ****
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"01111110", -- b **
205
"00000000", -- c **
"00000000", -- d ******
"00000000", -- e
"00000000", -- f
-- code x32
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"00000110", -- 4 **
"00001100", -- 5 **
"00011000", -- 6 **
"00110000", -- 7 **
"01100000", -- 8 **
"11000000", -- 9 **
"11000110", -- a ** **
"11111110", -- b *******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x33
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"00000110", -- 4 **
"00000110", -- 5 **
"00111100", -- 6 ****
"00000110", -- 7 **
"00000110", -- 8 **
"00000110", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x34
"00000000", -- 0
"00000000", -- 1
"00001100", -- 2 **
"00011100", -- 3 ***
"00111100", -- 4 ****
"01101100", -- 5 ** **
"11001100", -- 6 ** **
"11111110", -- 7 *******
"00001100", -- 8 **
"00001100", -- 9 **
"00001100", -- a **
"00011110", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x35
"00000000", -- 0
"00000000", -- 1
"11111110", -- 2 *******
"11000000", -- 3 **
"11000000", -- 4 **
"11000000", -- 5 **
"11111100", -- 6 ******
"00000110", -- 7 **
"00000110", -- 8 **
"00000110", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x36
"00000000", -- 0
"00000000", -- 1
"00111000", -- 2 ***
"01100000", -- 3 **
"11000000", -- 4 **
"11000000", -- 5 **
"11111100", -- 6 ******
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x37
"00000000", -- 0
"00000000", -- 1
"11111110", -- 2 *******
"11000110", -- 3 ** **
"00000110", -- 4 **
"00000110", -- 5 **
"00001100", -- 6 **
"00011000", -- 7 **
"00110000", -- 8 **
"00110000", -- 9 **
"00110000", -- a **
"00110000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x38
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"01111100", -- 6 *****
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x39
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"01111110", -- 6 ******
"00000110", -- 7 **
"00000110", -- 8 **
"00000110", -- 9 **
"00001100", -- a **
"01111000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3a
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00011000", -- 4 **
"00011000", -- 5 **
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00011000", -- 9 **
"00011000", -- a **
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3b
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00011000", -- 4 **
"00011000", -- 5 **
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00011000", -- 9 **
"00011000", -- a **
"00110000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3c
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000110", -- 3 **
"00001100", -- 4 **
206
"00011000", -- 5 **
"00110000", -- 6 **
"01100000", -- 7 **
"00110000", -- 8 **
"00011000", -- 9 **
"00001100", -- a **
"00000110", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3d
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111110", -- 5 ******
"00000000", -- 6
"00000000", -- 7
"01111110", -- 8 ******
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3e
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"01100000", -- 3 **
"00110000", -- 4 **
"00011000", -- 5 **
"00001100", -- 6 **
"00000110", -- 7 **
"00001100", -- 8 **
"00011000", -- 9 **
"00110000", -- a **
"01100000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x3f
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"00001100", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00000000", -- 9
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x40
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"11011110", -- 6 ** ****
"11011110", -- 7 ** ****
"11011110", -- 8 ** ****
"11011100", -- 9 ** ***
"11000000", -- a **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x41
"00000000", -- 0
"00000000", -- 1
"00010000", -- 2 *
"00111000", -- 3 ***
"01101100", -- 4 ** **
"11000110", -- 5 ** **
"11000110", -- 6 ** **
"11111110", -- 7 *******
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"11000110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x42
"00000000", -- 0
"00000000", -- 1
"11111100", -- 2 ******
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01111100", -- 6 *****
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"11111100", -- b ******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x43
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"01100110", -- 3 ** **
"11000010", -- 4 ** *
"11000000", -- 5 **
"11000000", -- 6 **
"11000000", -- 7 **
"11000000", -- 8 **
"11000010", -- 9 ** *
"01100110", -- a ** **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x44
"00000000", -- 0
"00000000", -- 1
"11111000", -- 2 *****
"01101100", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01100110", -- 6 ** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01101100", -- a ** **
"11111000", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x45
"00000000", -- 0
"00000000", -- 1
"11111110", -- 2 *******
"01100110", -- 3 ** **
"01100010", -- 4 ** *
"01101000", -- 5 ** *
"01111000", -- 6 ****
"01101000", -- 7 ** *
"01100000", -- 8 **
"01100010", -- 9 ** *
"01100110", -- a ** **
"11111110", -- b *******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x46
"00000000", -- 0
"00000000", -- 1
"11111110", -- 2 *******
"01100110", -- 3 ** **
"01100010", -- 4 ** *
"01101000", -- 5 ** *
"01111000", -- 6 ****
"01101000", -- 7 ** *
"01100000", -- 8 **
"01100000", -- 9 **
"01100000", -- a **
"11110000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
207
"00000000", -- f
-- code x47
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"01100110", -- 3 ** **
"11000010", -- 4 ** *
"11000000", -- 5 **
"11000000", -- 6 **
"11011110", -- 7 ** ****
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"01100110", -- a ** **
"00111010", -- b *** *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x48
"00000000", -- 0
"00000000", -- 1
"11000110", -- 2 ** **
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"11111110", -- 6 *******
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"11000110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x49
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4a
"00000000", -- 0
"00000000", -- 1
"00011110", -- 2 ****
"00001100", -- 3 **
"00001100", -- 4 **
"00001100", -- 5 **
"00001100", -- 6 **
"00001100", -- 7 **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01111000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4b
"00000000", -- 0
"00000000", -- 1
"11100110", -- 2 *** **
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01101100", -- 5 ** **
"01111000", -- 6 ****
"01111000", -- 7 ****
"01101100", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"11100110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4c
"00000000", -- 0
"00000000", -- 1
"11110000", -- 2 ****
"01100000", -- 3 **
"01100000", -- 4 **
"01100000", -- 5 **
"01100000", -- 6 **
"01100000", -- 7 **
"01100000", -- 8 **
"01100010", -- 9 ** *
"01100110", -- a ** **
"11111110", -- b *******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4d
"00000000", -- 0
"00000000", -- 1
"11000011", -- 2 ** **
"11100111", -- 3 *** ***
"11111111", -- 4 ********
"11111111", -- 5 ********
"11011011", -- 6 ** ** **
"11000011", -- 7 ** **
"11000011", -- 8 ** **
"11000011", -- 9 ** **
"11000011", -- a ** **
"11000011", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4e
"00000000", -- 0
"00000000", -- 1
"11000110", -- 2 ** **
"11100110", -- 3 *** **
"11110110", -- 4 **** **
"11111110", -- 5 *******
"11011110", -- 6 ** ****
"11001110", -- 7 ** ***
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"11000110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x4f
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x50
"00000000", -- 0
"00000000", -- 1
"11111100", -- 2 ******
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01111100", -- 6 *****
"01100000", -- 7 **
"01100000", -- 8 **
"01100000", -- 9 **
"01100000", -- a **
"11110000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x51
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"11000110", -- 6 ** **
"11000110", -- 7 ** **
208
"11000110", -- 8 ** **
"11010110", -- 9 ** * **
"11011110", -- a ** ****
"01111100", -- b *****
"00001100", -- c **
"00001110", -- d ***
"00000000", -- e
"00000000", -- f
-- code x52
"00000000", -- 0
"00000000", -- 1
"11111100", -- 2 ******
"01100110", -- 3 ** **
"01100110", -- 4 ** **
"01100110", -- 5 ** **
"01111100", -- 6 *****
"01101100", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"11100110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x53
"00000000", -- 0
"00000000", -- 1
"01111100", -- 2 *****
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"01100000", -- 5 **
"00111000", -- 6 ***
"00001100", -- 7 **
"00000110", -- 8 **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x54
"00000000", -- 0
"00000000", -- 1
"11111111", -- 2 ********
"11011011", -- 3 ** ** **
"10011001", -- 4 * ** *
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x55
"00000000", -- 0
"00000000", -- 1
"11000110", -- 2 ** **
"11000110", -- 3 ** **
"11000110", -- 4 ** **
"11000110", -- 5 ** **
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x56
"00000000", -- 0
"00000000", -- 1
"11000011", -- 2 ** **
"11000011", -- 3 ** **
"11000011", -- 4 ** **
"11000011", -- 5 ** **
"11000011", -- 6 ** **
"11000011", -- 7 ** **
"11000011", -- 8 ** **
"01100110", -- 9 ** **
"00111100", -- a ****
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x57
"00000000", -- 0
"00000000", -- 1
"11000011", -- 2 ** **
"11000011", -- 3 ** **
"11000011", -- 4 ** **
"11000011", -- 5 ** **
"11000011", -- 6 ** **
"11011011", -- 7 ** ** **
"11011011", -- 8 ** ** **
"11111111", -- 9 ********
"01100110", -- a ** **
"01100110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x58
"00000000", -- 0
"00000000", -- 1
"11000011", -- 2 ** **
"11000011", -- 3 ** **
"01100110", -- 4 ** **
"00111100", -- 5 ****
"00011000", -- 6 **
"00011000", -- 7 **
"00111100", -- 8 ****
"01100110", -- 9 ** **
"11000011", -- a ** **
"11000011", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x59
"00000000", -- 0
"00000000", -- 1
"11000011", -- 2 ** **
"11000011", -- 3 ** **
"11000011", -- 4 ** **
"01100110", -- 5 ** **
"00111100", -- 6 ****
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5a
"00000000", -- 0
"00000000", -- 1
"11111111", -- 2 ********
"11000011", -- 3 ** **
"10000110", -- 4 * **
"00001100", -- 5 **
"00011000", -- 6 **
"00110000", -- 7 **
"01100000", -- 8 **
"11000001", -- 9 ** *
"11000011", -- a ** **
"11111111", -- b ********
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5b
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"00110000", -- 3 **
"00110000", -- 4 **
"00110000", -- 5 **
"00110000", -- 6 **
"00110000", -- 7 **
"00110000", -- 8 **
"00110000", -- 9 **
"00110000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5c
209
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"10000000", -- 3 *
"11000000", -- 4 **
"11100000", -- 5 ***
"01110000", -- 6 ***
"00111000", -- 7 ***
"00011100", -- 8 ***
"00001110", -- 9 ***
"00000110", -- a **
"00000010", -- b *
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5d
"00000000", -- 0
"00000000", -- 1
"00111100", -- 2 ****
"00001100", -- 3 **
"00001100", -- 4 **
"00001100", -- 5 **
"00001100", -- 6 **
"00001100", -- 7 **
"00001100", -- 8 **
"00001100", -- 9 **
"00001100", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5e
"00010000", -- 0 *
"00111000", -- 1 ***
"01101100", -- 2 ** **
"11000110", -- 3 ** **
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x5f
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"11111111", -- d ********
"00000000", -- e
"00000000", -- f
-- code x60
"00110000", -- 0 **
"00110000", -- 1 **
"00011000", -- 2 **
"00000000", -- 3
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x61
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111000", -- 5 ****
"00001100", -- 6 **
"01111100", -- 7 *****
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01110110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x62
"00000000", -- 0
"00000000", -- 1
"11100000", -- 2 ***
"01100000", -- 3 **
"01100000", -- 4 **
"01111000", -- 5 ****
"01101100", -- 6 ** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x63
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11000000", -- 7 **
"11000000", -- 8 **
"11000000", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x64
"00000000", -- 0
"00000000", -- 1
"00011100", -- 2 ***
"00001100", -- 3 **
"00001100", -- 4 **
"00111100", -- 5 ****
"01101100", -- 6 ** **
"11001100", -- 7 ** **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01110110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x65
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11111110", -- 7 *******
"11000000", -- 8 **
"11000000", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x66
"00000000", -- 0
"00000000", -- 1
"00111000", -- 2 ***
"01101100", -- 3 ** **
"01100100", -- 4 ** *
"01100000", -- 5 **
"11110000", -- 6 ****
"01100000", -- 7 **
"01100000", -- 8 **
"01100000", -- 9 **
210
"01100000", -- a **
"11110000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x67
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01110110", -- 5 *** **
"11001100", -- 6 ** **
"11001100", -- 7 ** **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01111100", -- b *****
"00001100", -- c **
"11001100", -- d ** **
"01111000", -- e ****
"00000000", -- f
-- code x68
"00000000", -- 0
"00000000", -- 1
"11100000", -- 2 ***
"01100000", -- 3 **
"01100000", -- 4 **
"01101100", -- 5 ** **
"01110110", -- 6 *** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"11100110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x69
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00011000", -- 3 **
"00000000", -- 4
"00111000", -- 5 ***
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x6a
"00000000", -- 0
"00000000", -- 1
"00000110", -- 2 **
"00000110", -- 3 **
"00000000", -- 4
"00001110", -- 5 ***
"00000110", -- 6 **
"00000110", -- 7 **
"00000110", -- 8 **
"00000110", -- 9 **
"00000110", -- a **
"00000110", -- b **
"01100110", -- c ** **
"01100110", -- d ** **
"00111100", -- e ****
"00000000", -- f
-- code x6b
"00000000", -- 0
"00000000", -- 1
"11100000", -- 2 ***
"01100000", -- 3 **
"01100000", -- 4 **
"01100110", -- 5 ** **
"01101100", -- 6 ** **
"01111000", -- 7 ****
"01111000", -- 8 ****
"01101100", -- 9 ** **
"01100110", -- a ** **
"11100110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x6c
"00000000", -- 0
"00000000", -- 1
"00111000", -- 2 ***
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"00011000", -- 6 **
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00111100", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x6d
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11100110", -- 5 *** **
"11111111", -- 6 ********
"11011011", -- 7 ** ** **
"11011011", -- 8 ** ** **
"11011011", -- 9 ** ** **
"11011011", -- a ** ** **
"11011011", -- b ** ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x6e
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11011100", -- 5 ** ***
"01100110", -- 6 ** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"01100110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x6f
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x70
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11011100", -- 5 ** ***
"01100110", -- 6 ** **
"01100110", -- 7 ** **
"01100110", -- 8 ** **
"01100110", -- 9 ** **
"01100110", -- a ** **
"01111100", -- b *****
"01100000", -- c **
"01100000", -- d **
"11110000", -- e ****
"00000000", -- f
-- code x71
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
211
"00000000", -- 3
"00000000", -- 4
"01110110", -- 5 *** **
"11001100", -- 6 ** **
"11001100", -- 7 ** **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01111100", -- b *****
"00001100", -- c **
"00001100", -- d **
"00011110", -- e ****
"00000000", -- f
-- code x72
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11011100", -- 5 ** ***
"01110110", -- 6 *** **
"01100110", -- 7 ** **
"01100000", -- 8 **
"01100000", -- 9 **
"01100000", -- a **
"11110000", -- b ****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x73
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"01111100", -- 5 *****
"11000110", -- 6 ** **
"01100000", -- 7 **
"00111000", -- 8 ***
"00001100", -- 9 **
"11000110", -- a ** **
"01111100", -- b *****
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x74
"00000000", -- 0
"00000000", -- 1
"00010000", -- 2 *
"00110000", -- 3 **
"00110000", -- 4 **
"11111100", -- 5 ******
"00110000", -- 6 **
"00110000", -- 7 **
"00110000", -- 8 **
"00110000", -- 9 **
"00110110", -- a ** **
"00011100", -- b ***
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x75
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11001100", -- 5 ** **
"11001100", -- 6 ** **
"11001100", -- 7 ** **
"11001100", -- 8 ** **
"11001100", -- 9 ** **
"11001100", -- a ** **
"01110110", -- b *** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x76
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11000011", -- 5 ** **
"11000011", -- 6 ** **
"11000011", -- 7 ** **
"11000011", -- 8 ** **
"01100110", -- 9 ** **
"00111100", -- a ****
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x77
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11000011", -- 5 ** **
"11000011", -- 6 ** **
"11000011", -- 7 ** **
"11011011", -- 8 ** ** **
"11011011", -- 9 ** ** **
"11111111", -- a ********
"01100110", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x78
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11000011", -- 5 ** **
"01100110", -- 6 ** **
"00111100", -- 7 ****
"00011000", -- 8 **
"00111100", -- 9 ****
"01100110", -- a ** **
"11000011", -- b ** **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x79
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11000110", -- 5 ** **
"11000110", -- 6 ** **
"11000110", -- 7 ** **
"11000110", -- 8 ** **
"11000110", -- 9 ** **
"11000110", -- a ** **
"01111110", -- b ******
"00000110", -- c **
"00001100", -- d **
"11111000", -- e *****
"00000000", -- f
-- code x7a
"00000000", -- 0
"00000000", -- 1
"00000000", -- 2
"00000000", -- 3
"00000000", -- 4
"11111110", -- 5 *******
"11001100", -- 6 ** **
"00011000", -- 7 **
"00110000", -- 8 **
"01100000", -- 9 **
"11000110", -- a ** **
"11111110", -- b *******
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x7b
"00000000", -- 0
"00000000", -- 1
"00001110", -- 2 ***
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"01110000", -- 6 ***
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00001110", -- b ***
"00000000", -- c
212
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x7c
"00000000", -- 0
"00000000", -- 1
"00011000", -- 2 **
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"00000000", -- 6
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"00011000", -- b **
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x7d
"00000000", -- 0
"00000000", -- 1
"01110000", -- 2 ***
"00011000", -- 3 **
"00011000", -- 4 **
"00011000", -- 5 **
"00001110", -- 6 ***
"00011000", -- 7 **
"00011000", -- 8 **
"00011000", -- 9 **
"00011000", -- a **
"01110000", -- b ***
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x7e
"00000000", -- 0
"00000000", -- 1
"01110110", -- 2 *** **
"11011100", -- 3 ** ***
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000", -- f
-- code x7f
"00000000", -- 0
"00000110", -- 1 **
"00001100", -- 2 **
"00011000", -- 3 **
"00000000", -- 4
"00000000", -- 5
"00000000", -- 6
"00000000", -- 7
"00000000", -- 8
"00000000", -- 9
"00000000", -- a
"00000000", -- b
"00000000", -- c
"00000000", -- d
"00000000", -- e
"00000000" -- f
);
begin
process(clk)
begin
if (clk'event and clk='1') then
addr_reg <= addr;
end if;
end process;
data <= ROM(to_integer(unsigned(addr_reg)));
end font_rom;
213
Anexo K – Código em VHDL da interligação dos módulos do sintetizador
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Sintetizador is
Generic ( ADDR_WIDTH : INTEGER :=10;
DATA_WIDTH : INTEGER :=20);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
ps2_clk : in STD_LOGIC;
ps2_data : in STD_LOGIC;
frequencia1 : out STD_LOGIC;
frequencia2 : out STD_LOGIC;
frequencia3 : out STD_LOGIC;
frequencia4 : out STD_LOGIC;
frequencia5 : out STD_LOGIC;
an : out STD_LOGIC_VECTOR (3 downto 0);
sseg : out STD_LOGIC_VECTOR (7 downto 0);
h_sync, v_sync : out STD_LOGIC;
rgb : out STD_LOGIC_VECTOR (7 downto 0));
end Sintetizador;
architecture sintetizador of Sintetizador is
signal ps2_done_tick, data_done_tick : std_logic;
signal processamento_enable, reseta_processamento : std_logic;
signal ps2_out, tecla_out : std_logic_vector(7 downto 0);
signal we, enable_mem1, enable_mem2, enable_mem3 : std_logic;
signal addr : std_logic_vector (ADDR_WIDTH-1 downto 0);
signal din : std_logic_vector (DATA_WIDTH-1 downto 0);
signal dout_mem1, dout_mem2, dout_mem3 : std_logic_vector (DATA_WIDTH-1 downto 0);
signal nota1, nota2, nota3, nota4, nota5, nota1_mod, nota2_mod, nota3_mod, nota4_mod, nota5_mod :
std_logic_vector(5 downto 0);
signal modulacao_enable : std_logic;
signal modulacao : std_logic_vector (4 downto 0);
signal estado : std_logic_vector (3 downto 0);
begin
entrada_ps2_unit : entity work.Entrada_ps2(entrada_ps2)
port map ( clk=>clk, rst=>rst,
ps2_clk=>ps2_clk, ps2_data=>ps2_data,
ps2_out=>ps2_out, ps2_done_tick=>ps2_done_tick);
modo_operação_unit : entity work.Modo_operacao(modo_operacao)
generic map ( DATA_WIDTH=>DATA_WIDTH, ADDR_WIDTH=>ADDR_WIDTH)
port map ( clk=>clk, rst=>rst,
ps2_in=>ps2_out, ps2_done_tick=>ps2_done_tick,
processamento_enable=>processamento_enable, tecla_out=>tecla_out,
data_done_tick=>data_done_tick,
reseta_processamento=>reseta_processamento,
we=>we, enable_mem1=>enable_mem1, enable_mem2=>enable_mem2,
enable_mem3=>enable_mem3,
addr=>addr, din=>din, dout_mem1=>dout_mem1,
dout_mem2=>dout_mem2, dout_mem3=>dout_mem3,
modulacao=>modulacao, modulacao_enable=>modulacao_enable,
an=>an, sseg=>sseg, estado=>estado);
memoria1_unit : entity work.Memoria(memoria)
generic map ( DATA_WIDTH=>DATA_WIDTH, ADDR_WIDTH=>ADDR_WIDTH)
214
port map ( clk=>clk, enable=>enable_mem1, we=>we, addr=>addr, din=>din,
dout=>dout_mem1);
memoria2_unit : entity work.Memoria(memoria)
generic map ( DATA_WIDTH=>DATA_WIDTH, ADDR_WIDTH=>ADDR_WIDTH)
port map ( clk=>clk, enable=>enable_mem2, we=>we, addr=>addr, din=>din,
dout=>dout_mem2);
memoria3_unit : entity work.Memoria(memoria)
generic map ( DATA_WIDTH=>DATA_WIDTH, ADDR_WIDTH=>ADDR_WIDTH)
port map ( clk=>clk, enable=>enable_mem3, we=>we, addr=>addr, din=>din,
dout=>dout_mem3);
processamento_notas_unit : entity work.Processamento_notas(processamento_notas)
port map ( clk=>clk, rst=>rst,
ps2_done_tick=>data_done_tick,
data_in=>tecla_out, processamento_enable=>processamento_enable,
reseta_processamento=>reseta_processamento,
freq1=>nota1, freq2=>nota2, freq3=>nota3,
freq4=>nota4, freq5=>nota5);
modulacao_unit : entity work.Modulacao(modulacao)
port map ( modulacao_enable=>modulacao_enable, modulacao=>modulacao,
freq1=>nota1, freq2=>nota2, freq3=>nota3,
freq4=>nota4, freq5=>nota5, freq_mod1=>nota1_mod, freq_mod2=>nota2_mod,
freq_mod3=>nota3_mod, freq_mod4=>nota4_mod, freq_mod5=>nota5_mod);
gerador1_unit : entity work.Gerador_de_frequencias(gerador_de_frequencias)
port map ( clk=>clk, rst=>rst,
nota_in=>nota1_mod, freq_out=>frequencia1);
gerador2_unit : entity work.Gerador_de_frequencias(gerador_de_frequencias)
port map ( clk=>clk, rst=>rst,
nota_in=>nota2_mod, freq_out=>frequencia2);
gerador3_unit : entity work.Gerador_de_frequencias(gerador_de_frequencias)
port map ( clk=>clk, rst=>rst,
nota_in=>nota3_mod, freq_out=>frequencia3);
gerador4_unit : entity work.Gerador_de_frequencias(gerador_de_frequencias)
port map ( clk=>clk, rst=>rst,
nota_in=>nota4_mod, freq_out=>frequencia4);
gerador5_unit : entity work.Gerador_de_frequencias(gerador_de_frequencias)
port map ( clk=>clk, rst=>rst,
nota_in=>nota5_mod, freq_out=>frequencia5);
controle_VGA_unit : entity work.Controle_VGA(controle_vga)
port map ( clk=>clk, rst=>rst, estado=>estado, h_sync=>h_sync, v_sync=>v_sync,
nota1_mod=>nota1_mod, nota2_mod=>nota2_mod,
nota3_mod=>nota3_mod,
nota4_mod=>nota4_mod, nota5_mod=>nota5_mod, rgb=>rgb);
end sintetizador;
215
Anexo L – Arquivo ucf do sintetizador de sons
NET "clk" LOC = "B8";
NET "rst" LOC = "H13";
NET "ps2_clk" LOC = "R12";
NET "ps2_data" LOC = "P11";
NET "an(0)" LOC = "F17";
NET "an(1)" LOC = "H17";
NET "an(2)" LOC = "C18";
NET "an(3)" LOC = "F15";
NET "sseg(0)" LOC = "L18";
NET "sseg(1)" LOC = "F18";
NET "sseg(2)" LOC = "D17";
NET "sseg(3)" LOC = "D16";
NET "sseg(4)" LOC = "G14";
NET "sseg(5)" LOC = "J17";
NET "sseg(6)" LOC = "H14";
NET "sseg(7)" LOC = "C17";
NET "frequencia1" LOC = "G15";
NET "frequencia2" LOC = "H15";
NET "frequencia3" LOC = "G13";
NET "frequencia4" LOC = "G16";
NET "frequencia5" LOC = "H16";
NET "rgb(0)" LOC = "R9";
NET "rgb(1)" LOC = "T8";
NET "rgb(2)" LOC = "R8";
NET "rgb(3)" LOC = "N8";
NET "rgb(4)" LOC = "P8";
NET "rgb(5)" LOC = "P6";
NET "rgb(6)" LOC = "U5";
NET "rgb(7)" LOC = "U4";
NET "h_sync" LOC = "T4";
NET "v_sync" LOC = "U3";