Post on 13-Dec-2018
|
por: Ricardo Ferreira (ee96168)
Orientadores de projecto: Professor Pedro Guedes de Oliveira Professor Vitor Grade Tavares
0. ÍNDICE
0. ÍNDICE .......................................................................................................................................... 2
1. INTRODUÇÃO ............................................................................................................................. 3
2. UM ESTUDO AO SISTEMA DE LOCALIZAÇÃO SONORO DO SER HUMANO............ 6
“INTERAURAL TIME DIFFERENCE” (ITD) ............................................................................. 8 “INTERAURAL INTENSITY DIFFERENCE” (IID) ................................................................... 8 O EXEMPLO HUMANO, APLICADO AO SISTEMA DE LOCALIZAÇÃO SONORO A IMPLEMENTAR ................................................................................................................................... 9
3. ALGORITMO ............................................................................................................................. 12
AQUISIÇÃO DOS SINAIS SONOROS................................................................................................... 12 CORRELAÇÃO CRUZADA ................................................................................................................. 13 EXTRACÇÃO DE RESULTADOS ........................................................................................................ 15 DIAGRAMA DE BLOCOS FINAL, REALIZADO EM SIMULINK, REPRESENTANDO O ALGORITMO: ......... 16 SIMULAÇÃO E TESTES EM SIMULINK.............................................................................................. 17
4. O SISTEMA DE LOCALIZAÇÃO SONORO IMPLEMENTADO EM VERILOG HDL . 18
IMPLEMENTAÇÃO DO ALGORITMO EM VERILOG ......................................................................... 20 ALGORITMO....................................................................................................................................... 21 DESCRIÇÃO DO BLOCO DE AQUISIÇÃO DE SINAIS: ........................................................................... 22 DESCRIÇÃO DO BLOCO DE CORRELAÇÃO CRUZADA E DETECÇÃO DO MÁXIMO:............................. 23 ALGORITMO DE CORRELAÇÃO CRUZADA E DE DETECÇÃO DE MÁXIMO.......................................... 24 CÓDIGO VERILOG HDL DO BLOCO DE CORRELAÇÃO_CRUZADA_E_MÁXIMO ................................ 26 DESCRIÇÃO DO BLOCO DE CALCULO DO ÂNGULO:........................................................................... 27 SIMULAÇÃO DO ALGORITMO EM VERILOG HDL.......................................................................... 28 PROGRAMAÇÃO DA FPGA .............................................................................................................. 30
5. CONCLUSÃO ............................................................................................................................. 31
6. BIBLIOGRAFIA E REFERÊNCIAS........................................................................................ 33
ANEXO I : ALGORITMO DE IMPLEMENTAÇÃO(SIMULINK) ......................................... 36
ANEXO II: CÓDIGO EM VERILOG HDL ................................................................................ 42
CÓDIGO FONTE ................................................................................................................................ 43 TESTBENCH .................................................................................................................................. 49
1. INTRODUÇÃO
Este projecto estuda uma possível implementação em FPGA (Field
Programmable Gate Arrays) de um sistema de localização sonoro em
tempo-real, usando dois microfones. Nesta implementação foi usada uma
técnica baseada na correlação cruzada dos dois sinais provenientes dos
microfones.
A localização sonora em tempo-real é indispensável em várias aplicações,
como é o caso de sistemas de reconhecimento de voz ou mesmo o caso da
teleconferência automática, em que são usados vectores de microfones que
adquirem diversos sinais sonoros, os quais são processados
simultaneamente.
O processamento em tempo-real de múltiplos sinais sonoros, tem
muitas vezes um custo muito elevado, uma vez que pode ser necessária a
utilização de vários processadores. Mesmo que fosse usado um
processador DSP (Digital Signal Processor) dedicado, é frequente que seja
necessário uma grande quantidade de potência, o que torna esta
implementação muito pouco prática para muitas aplicações.
Por exemplo, o “Huge Microphone Array”, um sistema desenvolvido
pela Brown University utiliza múltiplos processadores DSP e buffers para a
localização de som com um consumo de potência médio de 400mW por
microfone, o que ultrapassa largamente o potência disponível em
aplicações tais como PDAs (Personal Digital Assistant) e telemóveis. A
melhor solução para estas aplicações seria sem dúvida um chip VLSI (Very
Large Scale Integration) desenhado especificamente para o efeito.
Como um precursor de uma implementação VLSI, irá ser
demonstrada a implementação de um sistema de localização sonoro numa
FPGA. Neste caso, o sistema por inteiro (exceptuando o bloco analógico de
aquisição de som) vai utilizar como plataforma a própria FPGA. Vai ser
ainda possível observar a eficiência do algoritmo proposto, bem como a
sua implementação em hardware, o que torna este método bastante
simples e, que entre outras vantagens, reduz significativamente a potência
média consumida.
Como ponto de partida para o estudo da localização sonora usando
dois microfones, foi tomado o caso do ser humano. A localização do som
através da audição do ser humano pode ser separada em dois tipos. A
localização monaural, que permite localizar as fontes sonoras utilizando
apenas um ouvido, e a localização biaural, que como o próprio nome
indica, e em contraste com a primeira, permite localizar a fonte usando a
diferença temporal do som que chega a cada um dos ouvidos. Nesta última
é notória a semelhança ao que se pretende implementar neste projecto. A
localização biaural do sistema auditivo humano, é portanto uma analogia
quase perfeita à utilização de dois microfones para a detecção da
localização de uma fonte de som.
Numa outra fase, será estudado o algoritmo que vai levar à
implementação do sistema. Neste caso, como já foi descrito, o coração do
algoritmo, e pelo qual tudo o resto vai girar à volta, é utilizada a correlação
cruzada entre os dois sons obtidos para determinar o atraso entre os
mesmo. Como complemento para o algoritmo final será necessário estudar
qual o melhor método para o tratamento dos sinais adquiridos e claro, qual
a melhor maneira de retirar do sinal resultante, a informação necessária e
como a usar de modo a se extrair o resultado pretendido.
O algoritmo final, será descrito em Verilog HDL (Hardware
Description Language), uma linguagem de descrição de hardware usada
para projectar sistemas electrónicos. Verilog, é a linguagem HDL mais
usada, actualmente utilizada por cerca 50,000 desenhadores. É uma
linguagem na qual, para se poder implementar ao nível do hardware, é
necessário definir os vários caminhos possíveis entre os blocos, consoante
o que se tenta projectar. No fundo é necessário cobrir todas as hipóteses,
o que neste caso, aproxima bastante esta linguagem a uma linguagem de
baixo nível. No entanto, Verilog HDL não pode ser considerada como tal,
pois é bastante mais abstracta e subjectiva. Em suma, para se projectar um
sistema em hardware usando Verilog HDL é necessário ter-se algum
cuidado, nomeadamente para que seja passada uma ideia objectiva do que
se pretende implementar.
2. UM ESTUDO AO SISTEMA DE LOCALIZAÇÃO SONORO DO SER HUMANO
O sistema tridimensional de localização sonora do ser humano, tem
sido considerado um caso especial de localização passiva de um sistema
composto apenas por dois sensores: os ouvidos. Na maioria dos estudos
sobre o sistema de localização sonoro do ser humano, as fontes sonoras
estão restringidas a um dos planos: ou o plano horizontal ou o vertical.
Neste projecto, só será necessário o estudo da localização de sons no
plano horizontal, uma vez, que neste caso é que é necessária a utilização
de dois receptores de som. As ondas sonoras, incidentes nos ouvidos de
um indivíduo, são reflectidas pela cabeça no lado do som proveniente, e
refractadas para o ouvido que se encontra do outro lado da cabeça. Estas
reflexões e refracções produzem ITDs (Interaural Time Differences) e IIDs
(Interaural Intensity Differences), que são as variáveis necessárias ao
cálculo da direcção a que a fonte sonora se encontra.
Para componente sonoras de baixa frequência, (abaixo de 1500Hz
para humanos), a diferença temporal entre os dois sensores sonoros (ITD)
causada pela sua diferença de fase, pode ser usada para localizar a fonte
sonora. Para estas frequências, o comprimento de onda do som, é pelo
menos diversas vezes maior do que a cabeça, e a quantidade de
“shadowing” (que depende do comprimento de onda do som comparado
com as dimensões da cabeça) é negligenciável. A localização através do
ITD é um sistema muito bem estudado em Biologia.
Acima de 3000Hz as diferenças de fase entre dois sinais sonoros
tornam-se ambíguos por múltiplos de 360º e assim deixam de ser fiáveis
para o sistema. Para estas frequências elevadas, o comprimento de onda
do som é suficientemente pequeno para se notar uma atenuação entre as
duas ondas, que resulta da presença física de um obstáculo, que neste
caso é a cabeça humana. A diferença de intensidade das magnitudes
logarítmicas nos ouvidos fornece-nos uma importante diferença de
intensidade entre os dois sensores auditivos, o IID (Interaural Intensity
Difference), que pode ser usado para localizar a fonte de som. No intervalo
de frequência entre 1500Hz e 3000Hz, os estímulos são demasiado
grandes em frequência para se poder obter uma localização correcta
baseada no ITD, e apresentam também um comprimento de onda
demasiado longo para fornecerem um adequado IID. Por isso não é nada
surpreendente que a performance de um sistema de localização de sinais
sonoros nesta gama de frequências seja bastante pior. Um método para
resolver este problema seria o de usar microfones adicionais.
Assumindo que a cabeça e os ouvidos do ser humano são simétricos,
um estímulo presente em qualquer local no plano mediano não deverá
produzir quaisquer diferenças interaurais e desta maneira chegamos à
conclusão que as diferenças interaurais não produzem qualquer solução no
que diz respeito à localização vertical de uma fonte sonora.
Muitos estudos mostram que quando um ouvido está completamente
bloqueado os humanos conseguem ainda detectar a fonte do som, no
entanto, com pior resolução na direcção horizontal.
A localização monaural requer que a informação seja de algum modo
extraída de efeitos que dependem da direcção, como o caso de reflexões e
refracções do som provenientes do ouvido externo, cabeça, ombro ou
mesmo do tronco. Este conjunto de componentes direccionais, contribuem
para o cálculo da “Head Related Transfer Function” (HRTF) que representa
uma função de transferência dependente da direcção, e é aplicada ao som
recebido num sistema auditivo resultante, no centro da cabeça.
“INTERAURAL TIME DIFFERENCE” (ITD)
Como já foi afirmado anteriormente a incidência sonora no plano
horizontal pode ser localizada através da diferença de tempo interaural
baseada na diferença de fase das duas fontes sonoras. A baixas
frequências, no caso do ser humano, o ITD pode ser aproximado tal que:
)sin(3incc
aITD θ≈ [eq.1]
onde c é a velocidade do som no ambiente actual, a o raio da cabeça e θinc
o
ângulo de incidência.
“INTERAURAL INTENSITY DIFFERENCE” (IID)
A altas frequências, principal fonte para a localização de um som, passa a
ser a diferença interaural de intensidade (IID). Este é definido por:
RL PPdBIID log20log20)( −= [eq.2]
O exemplo humano, aplicado ao SISTEMA DE LOCALIZAÇÃO
SONORO a implementar
No sistema que se pretende implementar, foi proposto o estudo da
localização de som na sua componente horizontal. O método escolhido
baseia-se na diferença de tempo interaural (ITD), uma vez que é o método
mais viável de implementação devido à natureza das variáveis envolvidas.
Para isso foi escolhido um sistema em que os dois microfones se
distanciam em 24cm. Tal implica, que para se poder utilizar para cálculo
do ângulo o ITD e para se poder obter uma analise objectiva e precisa do
sinal, sem ambiguidades, o comprimento de onda do som tem que ser
inferior a esta distância, atribuindo assim à frequência um valor máximo
sensivelmente de 1500Hz.
maxfc
=λ [eq.3] Sendo λ o comprimento de onda, c a velocidade do som e fmax
a frequência máxima a que se pode obter resultados não ambíguos.
Uma vez que no caso estudado, não existe nenhum obstáculo entre os dois
sensores sonoros (microfones), foi necessário fazer alguns ajustes no que
diz respeito à equação resultante que leva ao cálculo do ângulo.
Assim, a equação agora usada, será:
)sin(2incc
aITD θ= [eq.4]
Desta maneira, não existe o factor de correcção inserido pelo
obstáculo que existia entre os dois microfones, a cabeça humana. É esta a
expressão que irá ser usada para o cálculo final do ângulo. Logo,
)2
arcsin(a
cITDinc
×=θ .[eq.5]
A figura seguinte, ilustra bem, a aplicação desta fórmula:
E de seguida é possível observar como varia o ângulo obtido na equação,
com a variação do ITD:
Pode-se observar, neste gráfico, que é possível obter uma relação linear até
valores perto de 70º, a partir deste ângulo, uma pequena variação no ITD,
leva a grandes variações na saída.
3. ALGORITMO
O objectivo do algoritmo a implementar é, através da entrada de dois
sinais, cada um proveniente de um microfone, testar qual a diferença de
fase entre eles. O método escolhido, e porventura o mais óbvio, foi o de
utilizar a correlação cruzada, para detectar o atraso entre os dois sinais. O
algoritmo vai centrar-se à volta desta ideia. No entanto, outros factores
foram necessários ter em conta, nomeadamente, a aquisição de dados e a
extracção de resultados.
Aquisição dos Sinais Sonoros
Os sinais provenientes dos microfones contém ruído. Este é um
factor que não é desejado pois pode provocar valores não verdadeiros à
saída do algoritmo. Uma solução possível, e que foi implementada para a
aquisição de sinais através da placa de som de um computador, é fazer
cada sinal passar por um bloco “threshold”. Esta solução faz com que o
sinal de entrada só seja espelhado na saída quando ultrapassa um
determinado valor, o valor de “threshold”.
Para um primeiro estudo de um possível algoritmo foi usada para
simulação a aplicação Simulink, ferramenta presente no programa MATLAB.
Esta aplicação contém várias “toolboxes” que por sua vez dispõe blocos
que executam funções específicas. Estes blocos podem ser interligados de
maneira a se obter um diagrama de blocos que transforme uma ou mais
entradas na saída que se pretende. Neste caso tem-se como entrada dois
sinais sonoros e como saída um valor que representa o ângulo de
desfasamento dos dois sinais.
Na entrada escolheu-se adquirir os sinais sonoros como dois
vectores com 512 posições, e cada amostra desses vectores tem 8 bits, o
que perfaz um total de 256 níveis de decisão para cada amostra. A
informação é adquirida a uma frequência de amostragem de 44100 Hz.
Isto significa que uma amostra demora 12ms a ser recebida. É importante
ter em atenção aos tempos de duração das diversas fases do processo para
que o sistema final seja o mais eficaz possível.
Correlação Cruzada
O próprio Simulink, contém um bloco que desempenha o papel da
Correlação Cruzada, no entanto é relevante estudar o que esta função
representa.
A correlação cruzada é uma função matemática que relaciona dois
sinais. Esta função é útil para a realização deste projecto, pois se os dois
sinais de entrada forem semelhantes, mas no entanto apresentarem uma
diferença de fase, a correlação cruzada informa-nos do desfasamento que
existe entre eles. No caso em estudo, é conveniente usar a correlação
cruzada discreta, representada pela seguinte função matemática:
[ ] [ ] [ ]∑∞
−∞=
−=h
knxkhny[eq.6]
, sendo h e x os sinais de entrada e y o sinal de saída.
O sinal resultante da correlação cruzada tem o dobro do tamanho
que os sinais de entrada. O valor máximo do sinal resultante, é o que
indica o valor do atraso. Por exemplo, se o sinal correlacionado apresentar
o máximo exactamente no centro do gráfico, é porque os sinais de entrada
tem desfasamento nulo, ou seja, são coincidentes. Se o máximo no sinal
resultante não estiver situado no centro do gráfico, mas sim para um dos
lados, indica que os dois sinais se encontram desfasados. Para quantificar
o valor do desfasamento é necessário extrair a distância a que o máximo
se encontra do centro do gráfico. A este valor foi é normalmente atribuída
a designação de “lag”(retardação). Para calcular a “lag”, e como se tratam
de sinais discretos, observa-se qual a posição do vector em que ocorre o
máximo e contam-se as posições que existem entre o “local” em que este
ocorre e a posição central do vector. O valor obtido corresponde ao atraso
vectorial entre os dois sinais. É também muito importante perceber que
consoante a posição do máximo em relação ao centro do vector (à direita
ou à esquerda), é possível dizer qual dos sinais de entrada chega primeiro.
Este último factor é muito importante, caso contrário a informação obtida
através deste método seria ambígua.
As figuras seguintes demonstram um exemplo de dois sinais adquiridos
pelos respectivos microfones, e a correlação cruzada entre eles.
A partir da última figura podemos observar que o atraso entre os dois
sinais de entrada é de 11ms e que o microfone 1 está mais perto da fonte
de som, uma vez que o atraso é positivo.
Como conclusão, podemos dizer que a correlação cruzada é um óptimo
forma de se extrair o atraso entre dois sinais sonoros que provém da
mesma origem. Uma vez que os sinais são semelhantes, o resultado final
será um pico bem definido cujo índice será o atraso entre as entradas.
Extracção de Resultados Após o conhecimento do máximo, e do respectivo índice vectorial, e
por conseguinte, do atraso vectorial entre dois sinais semelhantes, é
necessário transformar esta informação na saída pretendida. Neste caso,
pretende-se saber qual o ângulo em que se encontra a fonte sonora,
relativamente ao centro do sistema dos dois microfones. Para tal é
obrigatório proceder-se a duas transformações:
- Primeiro, é necessário transformar o atraso vectorial no atraso temporal,
ou seja no ITD (“Interaural Time Difference”), e para isso tem que se
conhecer a frequência de amostragem a que o sinal é adquirido;
Sendo avect
o atraso vectorial entre os dois vectores, e fs a frequência de
amostragem tem-se:
s
vect
fa
ITD = [eq.7]
- Seguidamente, é necessário, a partir do ITD, calcular o ângulo,
usando a equação já referida anteriormente:
)2
arcsin(a
cITDinc
×=θ , [eq.8]
sendo c a velocidade do som e a a distância dos microfones ao centro do sistema.
Diagrama de blocos final, realizado em Simulink, representando o algoritmo:
É de realçar, como interpretação do esquemático representado acima
que o bloco com a função f(u) representa a junção das duas equações
definidas no ponto anterior. Como se pode observar, o sinal à entrada do
bloco corresponde ao índice do valor máximo, e na saída, que também é a
saída do sistema, obtém-se o ângulo.
Uma explicação bloco a bloco deste esquemático, encontra-se em
anexo, no final do relatório.
Simulação e testes em Simulink Para se testar os valores o modelo de blocos implementado em simulink,
optou-se pelo método seguinte. Foi medido com um transferidor o ângulo
real de uma fonte de som que foi depois comparado com o valor detectado
no modelo do Sistema de Localização Sonoro em Simulink. Obteve-se os
seguintes resultados:
Ângulo Real(º) Ângulo Detectado(º) Ângulo Real(º) Ângulo
Detectado(º) 0 1.841 0 1.841 15 11.11 -15 -16.41 30 26.73 -30 -24.68 45 44.97 -45 -47.63 60 60.15 -60 -68.68 75 74.82 -75 -74.52 90 84.77 -90 -84.77
Estes valores foram obtidos apenas com um teste realizado para cada
ângulo. Como se pode observar, os valores detectados não são muito
diferentes dos valores reais. Penso que a solução encontrada para definir
um algoritmo que calculasse o ângulo incidente no sistema de localização
é uma solução muito fiável tendo principalmente em conta a simplicidade
do algoritmo.
4. O SISTEMA DE LOCALIZAÇÃO SONORO IMPLEMENTADO EM VERILOG HDL Verilog HDL, sendo uma linguagem de descrição de hardware, é
usada para projectar um circuito digital, por exemplo, um processador,
uma memória ou um simples flip-flop. Isto quer dizer que, ao usar HDL,
pode-se descrever um qualquer hardware digital a qualquer nível.
Por exemplo, um flip-flop pode ser descrito em linguagem Verilog
HDL da seguinte maneira:
module d_ff ( d, clk, q, q_bar); input d ,clk; ouput q, q_bar; k) begin q <= d; q_bar <= !d; end e ndmodule
Podemos observar que é possível implementar um bloco que
descreve o desempenho do flip-flop descriminando as entradas e saídas.
No entanto, tanto é possível descrever-se um único flip-flop, como um
circuito onde existam milhares deles. É esta a verdadeira vantagem do
Verilog HDL, o facto de com um pequeno código se poder descrever um
circuito lógico com elevado número de “gates”, poupando-se bastante
tempo e, no entanto, permitir também editar cada uma delas.
A linguagem Verilog HDL, sendo a plataforma de implementação do
algoritmo na FPGA, necessita de uma descrição de todos os caminhos
possíveis e necessita que se garanta que apenas um e só um dos caminhos
é executado de cada vez.
Verilog HDL, é uma linguagem bastante flexível, mas que necessita
de ser restringida devido à sintetização. A síntese lógica, é o processo de
conversão de uma descrição de alto-nível de um circuito digital, numa
representação optimizada do mesmo circuito, mas agora ao nível das
portas lógicas. A síntese lógica faz uso de librarias “standard cell” que são
constituídas por portas lógicas simples como “AND”, “OR” e “NOR”, ou
“macro cells” como somadores, multiplexadores, memórias ou flip-flops.
Antes da fase de síntese, é preciso simular e testar o circuito em
causa, para tal é necessário criar um “testbench” que simula todas as
situações possíveis a que o circuito estaria sujeito. Este módulo de teste
não influência em nada a síntese do circuito descrito.
O esquema abaixo representado é útil para entender qual o papel de um
“testbench” no projecto de um circuito digital.
Geração de Estímulos
Análise de Resultados Circuito a
Fabricar
Testbench Modelo Sintetizável
Implementação do Algoritmo em Verilog Para implementar o algoritmo do Sistema de Localização Sonoro
decidiu-se construir uma máquina de estados. Esta máquina de estados
estaria dividida em 3 estados. O primeiro estado corresponde à aquisição
dos sinais, o segundo estado corresponde à correlação cruzada entre os
dois sinais, ao cálculo do máximo e do respectivo atraso vectorial do sinal
resultante e por fim, o terceiro estado realiza a transformação do atraso
vectorial no ângulo correspondente.
Algoritmo
AQUISIÇÃO DOS SINAIS:
• Preenche vector[1 ] • Preenche v ector[2 ]
Vecto res preench idos? Não
CORRELAÇÃO CRUZADA:• Preenche cada po sição do vect or
de correlação • Test a se o valor act ual da posição
do vecto r é m aio r do que o últ imo m áx imo
• Reto rna a dist ância do m áx im o ao centro do vect or
Todas as posições do vecto r result ant e
p reench idas?
Não
Sim
Sim
ESTAD O 1
ESTAD O 2
ESTAD O 3 CÁLCULO DO ÂNGULO:
• Calcula o ângulo , at ravés de um a “Look-Up Table”
Descrição do Bloco de Aquisição de Sinais:
begin:AQUISICAO_DO_SINAL if(i<=tamanho_vector-1) begin sinal_1[i]<=input_1; sinal_2[i]<=input_2; i<=i+1; end else begin estado<=estado+1; i<=0; end end
O bloco que faz a aquisição dos sinais, é bastante simples. Duas
amostras, correspondendo a cada um dos sinais, são adquiridas
paralelamente, num ciclo de relógio, até que as 512 posições dos vectores
estejam completamente preenchidas. Estes dois vectores, foram declarados
como memórias sintetizáveis, no início do código. E como já foi descrito
anteriormente, cada amostra tem 8 bits. Os tamanhos das memórias bem
como das amostras, foram escolhidos de modo a que o funcionamento do
sistema na FPGA seja eficiente, já que é necessário que, nomeadamente o
bloco de correlação seja executado no menor espaço de tempo possível.
Tal é necessário porque enquanto o bloco correlacional está a ser
executado, o sinal à entrada não se encontra a ser adquirido. Se este bloco
tiver uma duração excessiva, o sistema poderá ter perdas significativas de
informação. Se forem adquiridas
amostras de 16 bits, isso significa
que cada memória de cada sinal de
entrada representam 512x16=8192
flip-flops, o que provoca atrasos
significativos no desempenho do
sistema. Desta maneira, escolheu-se usar amostras de 8 bits, uma vez que
para o propósito 256 níveis de decisão serão suficientes e reduz-se assim
para metade o número de flip-flops usados.
No fim deste bloco, quando se detecta que os vectores se encontram
preenchidos, incrementa-se a variável de estado, passando o circuito para
o bloco seguinte. Neste caso, o bloco de correlação cruzada.
Descrição do Bloco de Correlação Cruzada e Detecção do Máximo: Este bloco, é sem dúvida, o bloco mais complexo dos três estados.
Ele próprio contém um sub-algoritmo que se pode dividir em duas partes:
correlação cruzada e detecção do máximo.
A correlação cruzada, como já foi visto anteriormente, é uma função
matemática em que o resultado final, no caso discreto, resulta num vector
com o dobro do tamanho das entradas. Cada posição do vector de saída,
resulta da soma das multiplicações da intersecção dos dois sinais de
entrada à medida que eles se cruzam. No fim do cálculo de cada uma das
posições do vector que resulta da correlação, é necessário fazer um “shift”
a um dos vectores de entrada de modo a que esse sinal vá deslizando,
posição a posição, à medida que passa pelo outro sinal de entrada. Para
tornar esta situação mais clara é necessário perceber o esquema que se
encontra na página seguinte.
Algoritmo de Correlação Cruzada e de Detecção de Máximo
Situação Inicial: • i=0; • j=0; • max_vector=512; • temp=0; • maximo=0; • atraso_vectorial=0;
Não
temp=sin_1[j]*sin_2[j]+temp; j++;
xcorr[i]>maximo?
Sim
i++; shift sinal 1;
j=max_vector ?
Não
xcorr[i]=temp;
Sim
maximo=xcorr[i]; atraso_vectorial=i;
i=2*max_vector-1?
Sim
Não
Como se pode verificar no fluxograma anterior, o teste do valor máximo é
feito quando se preenche cada posição do vector do sinal correlacionado. A
vantagem de se utilizar este método, e não o teste do valor máximo do
vector no final da correlação, é o facto de, para isso, se poder usar o
mesmo ciclo de relógio, e não desperdiçar tempo útil no cálculo. Ainda
outra vantagem é o facto de ser possível guardar apenas em dois registos a
informação necessária. Uma vez que os valores que nos interessam são o
máximo e a sua posição no vector, podemos ignorar o resto da informação
poupando assim recursos. Ou seja, para obtermos os valores pretendidos
não é necessário implementar uma memória para guardar todo o vector de
correlação.
Também para poupar tempo de processamento, decidiu-se, como se
pode ver no código a seguir descrito, calcular apenas os valores centrais do
vector correlação. Isto tem uma explicação muito simples. Para se obter
ângulo resultante mais próximo dos 90º, é necessário um atraso vectorial
de 31 posições, logo os valores com o atraso vectorial maior são
considerados inválidos. Desta maneira, só é necessário testar o máximo
valor dentro destes limites. No corrente estudado, o máximo têm
necessariamente de se situar entre a posição 480 e a posição 543 do
vector de correlação.
Adicionalmente, e pela sua facilidade de implementação foi criada
uma “flag” que indica se o máximo foi detectado do lado esquerdo ou o
lado direito do vector de correlação. Esta “flag”, portanto, é quem detém a
informação se a primeira onda a chegar se situa na primeira ou na segunda
entrada.
Código Verilog HDL do bloco de Correlação_Cruzada_e_Máximo
begin:CORRELACAO_CRUZADA_E_MAXIMO if(lag<=551) begin if(lag<=511) pointer<=tamanho_vector-1-lag; else pointer<=lag-tamanho_vector; if(pointer+index<tamanho_vector) begin //shift=lag if(lag<=511) begin temp1<=sinal_1[pointer+index]; temp2<=sinal_2[index]; reg_corr<=temp1*temp2+reg_corr; index<=index+1; end else begin //shift=2*tamanho_vector-1-lag temp1<=sinal_1[index]; temp2<=sinal_2[pointer+index]; reg_corr<=temp1*temp2+reg_corr; index<=index+1; end end else begin if(reg_corr>maximo) begin if(lag<=511) begin//Teste dos valores máximos ordem<=1; maximo<=reg_corr; indice<=pointer+1; temp_corr<=reg_corr; reg_corr<=0; index<=0; lag=lag+1; end else begin//Teste dos valores máximos ordem=0; maximo<=reg_corr; indice<=pointer+1; temp_corr<=reg_corr; reg_corr<=0; index<=0; lag=lag+1; end end else begin temp_corr<=reg_corr; reg_corr<=0; index<=0; lag=lag+1; //index_b<=0; end end end else begin estado<=estado+1; lag<=472; end end
Descrição do Bloco de Calculo do ângulo: Neste bloco final dependendo do valor do
atraso vectorial entre os dois vectores de
entrada é calculado o ângulo de incidência
do sinal sonoro no centro do sistema. Para
isso, foi construída uma “look-up table” que
para cada valor do atraso vectorial atribui
um ângulo correspondente calculado pela
junção das equações 7 e 8, onde se obtem
que o ângulo,
begin:CALCULO_DO_ANGULO case (indice) 0: angulo<=0; 1: angulo<=2; 2: angulo<=4; 3: angulo<=6; 4: angulo<=7; 5: angulo<=9; 6: angulo<=11; 7: angulo<=13; 8: angulo<=15; 9: angulo<=17; 10: angulo<=19; 11: angulo<=21; 12: angulo<=23; 13: angulo<=25; 14: angulo<=27; 15: angulo<=29; 16: angulo<=31; 17: angulo<=33; 18: angulo<=35; 19: angulo<=38; 20: angulo<=40; 21: angulo<=42; 22: angulo<=45; 23: angulo<=48; 24: angulo<=50; 25: angulo<=53; 26: angulo<=57; 27: angulo<=60; 28: angulo<=64; 29: angulo<=69; 30: angulo<=75; 31: angulo<=85; endcase estado<=0; temp_corr1<=0; temp_corr2<=0; end
)2af
ca
s
vect
××
arcsin(inc =θ [eq.9],
usando f
s=44100Hz, a=12cm e 340 m/s.
Este bloco é todo realizado num único ciclo
de relógio.
Simulação do Algoritmo em Verilog HDL Para testar o código Verilog HDL do algoritmo do sistema de localização
sonoro criado, foi necessário criar uma “testbench”. Nesta “testbench”
foram geradas duas meias ondas sinusoidais separadas por 25 ciclos de
relógio, ou seja, a última onda a ser gerada só é iniciada 25 posições
vectoriais depois da primeira. O código da “testbench” gerada encontra-se
em anexo, e a seguir estão demonstrados os resultados de simulação. A
primeira imagem representam as ondas de entrada a serem adquiridas no
primeiro estado do algoritmo:
É bem visível o atraso das duas ondas de entrada e se for tomada atenção
podemos observar a variável “i” que representa o índice dos vectores de
entrada, e que é incrementada à medida que os sinais são adquiridos.
A figura seguinte mostra um ciclo completo do algoritmo:
De realçar, no centro da figura o gráfico da correlação cruzada dos sinais
de entrada, onde se nota que o pico resultante está a pender para a direita.
Quando ocorre o valor máximo, alguns registos estagnam, como é o caso
do registo que guarda o valor máximo “maximo”, e o registo que detecta o
índice em que ele ocorre que se encontra directamente abaixo, é o registo
“indice”. É de salientar ainda, que o registo “ordem” é uma “flag” que indica
em que lado do vector é detectado o máximo. Repare-se que quando se
passa pelo centro do vector de correlação, o registo “ordem” passa a conter
o valor “0”. Quando o ciclo que executa a correlação e detecta o máximo
acaba, o registo “ângulo” adquire o valor correspondente ao índice
encontrado e começa uma nova aquisição de dados.
Programação da FPGA Após a síntese lógica, procede-se à programação da FPGA. Dependendo da
complexidade do circuito a implementar, a FPGA utilizada pode ter uma
frequência máxima de 4MHz. É necessário ter em conta este factor, uma
vez que o algoritmo foi programado para uma frequência de amostragem
de 44100Hz. O facto da FPGA poder ter uma frequência tão elevada é um
bastante positivo, pois faz com que o tempo de processamento do
algoritmo seja bastante mais curto. No entanto, é necessário assegurar que
os sinais de entrada são lidos a uma frequência de 44100Hz. Como é que
isto é possível? Uma solução possível, e a mais simples e usada, consiste
em dividir o relógio. Basicamente, quando os sinais estiverem a ser
adquiridos, carrega-se um contador, para, que entre cada amostra
adquirida, se espere um determinado tempo, de maneira a que os valores
sejam assimilados à frequência pretendida.
Na figura acima, podemos observar que a aquisição de dados, em relação
ao bloco que executa a correlação, demora muito pouco tempo, o que não
é bom. Isto implica que o sistema de escuta, esteja muito pouco tempo em
acção. O que pode não ser suficiente para detectar um som correctamente.
No entanto, a situação fica resolvida quando é aplicado o divisor de
relógio. Desta maneira, a aquisição dos sinais de entrada, para além de ser
na frequência correcta, ocupa também grande parte do ciclo, ou seja, está
maior parte do tempo à escuta.
5. CONCLUSÃO
O objectivo inicial de um projecto é o seu tema. Todavia, a
aprendizagem que advém de todo o processo de pesquisa para tornar o
objectivo possível, torna-se a verdadeira mais valia adquirida. No caso
deste projecto, a busca por um Sistema de Localização Sonoro, tornou-se
um fim para aprender os meios. Todas as decisões tomadas, foram
cuidadosamente pensadas para que a implementação aliasse a
simplicidade do circuito à eficiência do sistema e precisão do resultado
final. Penso que estes objectivos foram alcançados, no entanto, após o
cumprimento do que foi proposto, fica-se com a sensação que a partir
deste projecto poderia nascer outro que representasse o nível a seguir. No
fundo, é normal que no término de algo feito por nós com sucesso,
pensemos em objectivos de dificuldade mais elevada, a que chamamos
desafios.
O saber que foi adquirido durante a realização deste projecto,
envolveram vários níveis de saber. Ao nível mais baixo, que serviu de base
de sustentação para tudo o resto, estudou-se a melhor forma de
implementar o sistema, nomeadamente qual o método que se deveria usar
para calcular o atraso entre dois sinais. Chegou-se ao consenso que a
correlação cruzada seria a solução mais simples e mais acessível na sua
implementação ao nível do hardware. De seguida estudou-se um método
para adquirir os sinais sonoros e qual a melhor estratégia para os
manipular, sendo preciso também encontrar uma plataforma de simulação
para avaliar os resultados obtidos. Chegou-se à conclusão, que o programa
MATLAB possuía a ferramenta ideal para ser usada. Esta ferramenta
denomina-se Simulink. Foi estudada também uma solução para que os
sinais fossem adquiridos por um computador e fossem limpos de ruído. O
Simulink, tornou-se numa ferramenta muito útil, uma vez que permitiu
implementar de uma forma visual e simples todo o algoritmo estudado.
Uma vez que cada função era definida por blocos, tornou-se fácil o papel
da detecção de erros de implementação.
Na fase seguinte, foi posta a questão se se deveria prosseguir
usando circuitos analógicos, ou usando circuitos digitais. Uma vez que,
atendendo ao tempo disponível, para tornar possível a demonstração do
funcionamento do Sistema de Localização Sonoro, a implementação em
circuito analógico não seria possível, optou-se pela segunda hipótese.
Desta maneira, foi decidido usar como plataforma uma FPGA e a
descrição de hardware foi elaborada em Verilog HDL.
Chegou-se à conclusão, que Verilog HDL é uma linguagem muito
simples que veio revolucionar o desenho de circuitos VLSI. Para além de ser
de fácil aprendizagem torna-se numa ferramenta indispensável pela
maneira simples e objectiva como pode ser implementada. É muito
frequente, ao escrever o código-fonte, imaginar como cada bloco vai ser
implementado em circuito digital. Esta característica é muito útil pois
permite que haja uma consciência daquilo que é ou não possível
implementar.
Foi necessário perceber a síntese lógica, que é o que traduz o
código-fonte em HDL noutro de mais baixo nível. Foi preciso compreender
quais os tipos de código que não seriam possíveis implementar, atendendo
a regras e restrições que traduzem os limites físicos de um circuito digital.
Por fim, a compreensão do funcionamento de uma FPGA foi outro
conhecimento adquirido na busca de um resultado final que se possa
testar e demonstrar.
6. BIBLIOGRAFIA E REFERÊNCIAS
-“HDL CHIP DESIGN – A practical guide for designing, synthesizing and
simulating ASICs and FPGAs using VHDL or VERILOG”,
por Douglas J. Smith, Doone Publications
-“MATLAB – Signal Processing ToolBox (User´s Guide)”
The Mathworks inc.
-“DSP BLOCKSET – For use with Simulink® (User´s Guide)”
The Matworks
-“FPGA Compiler II/FPGA Express – Verilog HDL Reference Manual”,
version 1999.05, May 1999, SYNOPSIS®
-“Directional Hearing”,
por W.A.Yost e G.Gourevitch, Springer-Verlag, 1987
-“ASIC World”,
http://www.asic-world.com/verilog/index.html
-“Cross Correlation”,
http://astronomy.swin.edu.au/~pbourke/analysis/correlate/
-“Cross Correlation – from Mathworld”
http://mathworld.wolfram.com/Cross-Correlation.html
-“Multimedia Sensor Fusion for Intelligent Camera Control and Human-Computer Interaction-CHAPTER 3”, por Steven George Goodridge http://www.ie.ncsu.edu/kay/msf/sound.htm
-“SODAR – Sound Detecting and Ranging”, por Roy Richard Ha, Graham Richard Hull and Ryan Christopher king http://www.owlnet.rice.edu/~elec301/Projects00/sodar/index.htm -“A NEUROMORPHIC MICROPHONE FOR SOUND LOCALIZATION”, por CHIANG-JUNG PU -“NONNEGATIVE DECONVOLUTION FOR TIME OF ARRIVAL ESTIMATION”, por Yuanqing Lin, Daniel D. Lee, and Lawrence K. Saul -“Separating Three Simultaneous Speeches with Two Microphones by Integrating Auditory and Visual Processing”, por Hiroshi G. Okuno, Kazuhiro Nakadai, Tino Lourens_, and Hiroaki Kitano -“REAL-TIME SOUND LOCALIZATION USING FIELD-PROGRAMMABLE GATE ARRAYS”, por Duy Nguyen, Parham Aarabi, Ali Sheikholeslami -“A Biologically-Inspired Monaural Sound Localizer”, por John Harris, Chiang-Jung Pu, and Jose C. Principe
TESTBENCH /Escala temporal `timescale 10us/1ns //Modulo para a maquina de estados module tbench(); wire [6:0] angulo; reg reset; reg clk; reg [7:0] input_1; reg [7:0] input_2; maq_estados instancia( .clk(clk),.reset(reset),.input_1(input_1), .input_2(input_2),.angulo(angulo)); reg [7:0] index_table; reg [7:0] index_table1; reg [7:0] table_value; reg [7:0] table_value1; reg updown; reg updown1; reg [9:0] counter; //condições iniciais initial begin clk = 0; input_1 = 0; input_2 = 0; index_table=0; index_table1=0; updown=0; counter=25; #90000 $stop; end // relógio a 500 MHz always #1 clk = ~clk;
initial begin #1 reset=0; #1 reset=1; #1 reset=0; end always @(posedge clk) begin case(index_table) 0 : table_value=8'd1; 1 : table_value <=8'd2; 2 : table_value <=8'd4; 3 : table_value <=8'd5; 4 : table_value <=8'd7; 5 : table_value <=8'd9; 6 : table_value <=8'd10; 7 : table_value <=8'd12; 8 : table_value <=8'd13; 9 : table_value <=8'd15; 10 : table_value <=8'd16; 11 : table_value <=8'd18; 12 : table_value <=8'd20; 13 : table_value <=8'd21; 14 : table_value <=8'd23; 15 : table_value <=8'd24; 16 : table_value <=8'd26; 17 : table_value <=8'd27; 18 : table_value <=8'd29; 19 : table_value <=8'd30; 20 : table_value <=8'd32; 21 : table_value <=8'd34; 22 : table_value <=8'd35; 23 : table_value <=8'd37; 24 : table_value <=8'd38; 25 : table_value <=8'd40; 26 : table_value <=8'd41; 27 : table_value <=8'd43; 28 : table_value <=8'd44; 29 : table_value <=8'd46; 30 : table_value <=8'd47; 31 : table_value <=8'd49; 32 : table_value <=8'd51; 33 : table_value <=8'd52; 34 : table_value <=8'd54;
35 : table_value <=8'd55; 36 : table_value <=8'd57; 37 : table_value <=8'd58; 38 : table_value <=8'd60; 39 : table_value <=8'd61; 40 : table_value <=8'd63; 41 : table_value <=8'd64; 42 : table_value <=8'd66; 43 : table_value <=8'd67; 44 : table_value <=8'd69; 45 : table_value <=8'd70; 46 : table_value <=8'd72; 47 : table_value <=8'd73; 48 : table_value <=8'd75; 49 : table_value <=8'd76; 50 : table_value <=8'd78; 51 : table_value <=8'd79; 52 : table_value <=8'd81; 53 : table_value <=8'd82; 54 : table_value <=8'd84; 55 : table_value <=8'd85; 56 : table_value <=8'd87; 57 : table_value <=8'd88; 58 : table_value <=8'd90; 59 : table_value <=8'd91; 60 : table_value <=8'd93; 61 : table_value <=8'd94; 62 : table_value <=8'd95; 63 : table_value <=8'd97; 64 : table_value <=8'd98; 65 : table_value <=8'd100; 66 : table_value <=8'd101; 67 : table_value <=8'd103; 68 : table_value <=8'd104; 69 : table_value <=8'd105; 70 : table_value <=8'd107; 71 : table_value <=8'd108; 72 : table_value <=8'd110; 73 : table_value <=8'd111; 74 : table_value <=8'd113; 75 : table_value <=8'd114; 76 : table_value <=8'd115; 77 : table_value <=8'd117; 78 : table_value <=8'd118; 79 : table_value <=8'd120; 80 : table_value <=8'd121; 81 : table_value <=8'd122;
82 : table_value <=8'd124; 83 : table_value <=8'd125; 84 : table_value <=8'd126; 85 : table_value <=8'd128; 86 : table_value <=8'd129; 87 : table_value <=8'd130; 88 : table_value <=8'd132; 89 : table_value <=8'd133; 90 : table_value <=8'd134; 91 : table_value <=8'd136; 92 : table_value <=8'd137; 93 : table_value <=8'd138; 94 : table_value <=8'd140; 95 : table_value <=8'd141; 96 : table_value <=8'd142; 97 : table_value <=8'd144; 98 : table_value <=8'd145; 99 : table_value <=8'd146; 100 : table_value <=8'd147; 101 : table_value <=8'd149; 102 : table_value <=8'd150; 103 : table_value <=8'd151; 104 : table_value <=8'd153; 105 : table_value <=8'd154; 106 : table_value <=8'd155; 107 : table_value <=8'd156; 108 : table_value <=8'd158; 109 : table_value <=8'd159; 110 : table_value <=8'd160; 111 : table_value <=8'd161; 112 : table_value <=8'd162; 113 : table_value <=8'd164; 114 : table_value <=8'd165; 115 : table_value <=8'd166; 116 : table_value <=8'd167; 117 : table_value <=8'd168; 118 : table_value <=8'd170; 119 : table_value <=8'd171; 120 : table_value <=8'd172; 121 : table_value <=8'd173; 122 : table_value <=8'd174; 123 : table_value <=8'd175; 124 : table_value <=8'd176; 125 : table_value <=8'd178; 126 : table_value <=8'd179; 127 : table_value <=8'd180; 128 : table_value <=8'd181;
129 : table_value <=8'd182; 130 : table_value <=8'd183; 131 : table_value <=8'd184; 132 : table_value <=8'd185; 133 : table_value <=8'd186; 134 : table_value <=8'd187; 135 : table_value <=8'd188; 136 : table_value <=8'd189; 137 : table_value <=8'd191; 138 : table_value <=8'd192; 139 : table_value <=8'd193; 140 : table_value <=8'd194; 141 : table_value <=8'd195; 142 : table_value <=8'd196; 143 : table_value <=8'd197; 144 : table_value <=8'd198; 145 : table_value <=8'd199; 146 : table_value <=8'd200; 147 : table_value <=8'd201; 148 : table_value <=8'd202; 149 : table_value <=8'd202; 150 : table_value <=8'd203; 151 : table_value <=8'd204; 152 : table_value <=8'd205; 153 : table_value <=8'd206; 154 : table_value <=8'd207; 155 : table_value <=8'd208; 156 : table_value <=8'd209; 157 : table_value <=8'd210; 158 : table_value <=8'd211; 159 : table_value <=8'd212; 160 : table_value <=8'd212; 161 : table_value <=8'd213; 162 : table_value <=8'd214; 163 : table_value <=8'd215; 164 : table_value <=8'd216; 165 : table_value <=8'd217; 166 : table_value <=8'd218; 167 : table_value <=8'd218; 168 : table_value <=8'd219; 169 : table_value <=8'd220; 170 : table_value <=8'd221; 171 : table_value <=8'd221; 172 : table_value <=8'd222; 173 : table_value <=8'd223; 174 : table_value <=8'd224; 175 : table_value <=8'd225;
176 : table_value <=8'd225; 177 : table_value <=8'd226; 178 : table_value <=8'd227; 179 : table_value <=8'd227; 180 : table_value <=8'd228; 181 : table_value <=8'd229; 182 : table_value <=8'd230; 183 : table_value <=8'd230; 184 : table_value <=8'd231; 185 : table_value <=8'd232; 186 : table_value <=8'd232; 187 : table_value <=8'd233; 188 : table_value <=8'd233; 189 : table_value <=8'd234; 190 : table_value <=8'd235; 191 : table_value <=8'd235; 192 : table_value <=8'd236; 193 : table_value <=8'd236; 194 : table_value <=8'd237; 195 : table_value <=8'd238; 196 : table_value <=8'd238; 197 : table_value <=8'd239; 198 : table_value <=8'd239; 199 : table_value <=8'd240; 200 : table_value <=8'd240; 201 : table_value <=8'd241; 202 : table_value <=8'd241; 203 : table_value <=8'd242; 204 : table_value <=8'd242; 205 : table_value <=8'd243; 206 : table_value <=8'd243; 207 : table_value <=8'd244; 208 : table_value <=8'd244; 209 : table_value <=8'd245; 210 : table_value <=8'd245; 211 : table_value <=8'd246; 212 : table_value <=8'd246; 213 : table_value <=8'd246; 214 : table_value <=8'd247; 215 : table_value <=8'd247; 216 : table_value <=8'd248; 217 : table_value <=8'd248; 218 : table_value <=8'd248; 219 : table_value <=8'd249; 220 : table_value <=8'd249; 221 : table_value <=8'd249; 222 : table_value <=8'd250;
223 : table_value <=8'd250; 224 : table_value <=8'd250; 225 : table_value <=8'd251; 226 : table_value <=8'd251; 227 : table_value <=8'd251; 228 : table_value <=8'd251; 229 : table_value <=8'd252; 230 : table_value <=8'd252; 231 : table_value <=8'd252; 232 : table_value <=8'd252; 233 : table_value <=8'd253; 234 : table_value <=8'd253; 235 : table_value <=8'd253; 236 : table_value <=8'd253; 237 : table_value <=8'd253; 238 : table_value <=8'd254; 239 : table_value <=8'd254; 240 : table_value <=8'd254; 241 : table_value <=8'd254; 242 : table_value <=8'd254; 243 : table_value <=8'd254; 244 : table_value <=8'd254; 245 : table_value <=8'd254; 246 : table_value <=8'd255; 247 : table_value <=8'd255; 248 : table_value <=8'd255; 249 : table_value <=8'd255; 250 : table_value <=8'd255; 251 : table_value <=8'd255; 252 : table_value <=8'd255; 253 : table_value <=8'd255; 254 : table_value <=8'd255; 255 : table_value <=8'd255; endcase input_1=table_value; if(index_table==255 || updown==1) begin updown=1; index_table=index_table-5; end if(index_table==0 || updown==0) begin updown=0; index_table=index_table+5; end if (counter==0)
begin case(index_table1) 0 : table_value1=8'd1; 1 : table_value1 <=8'd2; 2 : table_value1 <=8'd4; 3 : table_value1 <=8'd5; 4 : table_value1 <=8'd7; 5 : table_value1 <=8'd9; 6 : table_value1 <=8'd10; 7 : table_value1 <=8'd12; 8 : table_value1 <=8'd13; 9 : table_value1 <=8'd15; 10 : table_value1 <=8'd16; 11 : table_value1 <=8'd18; 12 : table_value1 <=8'd20; 13 : table_value1 <=8'd21; 14 : table_value1 <=8'd23; 15 : table_value1 <=8'd24; 16 : table_value1 <=8'd26; 17 : table_value1 <=8'd27; 18 : table_value1 <=8'd29; 19 : table_value1 <=8'd30; 20 : table_value1 <=8'd32; 21 : table_value1 <=8'd34; 22 : table_value1 <=8'd35; 23 : table_value1 <=8'd37; 24 : table_value1 <=8'd38; 25 : table_value1 <=8'd40; 26 : table_value1 <=8'd41; 27 : table_value1 <=8'd43; 28 : table_value1 <=8'd44; 29 : table_value1 <=8'd46; 30 : table_value1 <=8'd47; 31 : table_value1 <=8'd49; 32 : table_value1 <=8'd51; 33 : table_value1 <=8'd52; 34 : table_value1 <=8'd54; 35 : table_value1 <=8'd55; 36 : table_value1 <=8'd57; 37 : table_value1 <=8'd58; 38 : table_value1 <=8'd60; 39 : table_value1 <=8'd61; 40 : table_value1 <=8'd63; 41 : table_value1 <=8'd64; 42 : table_value1 <=8'd66; 43 : table_value1 <=8'd67; 44 : table_value1 <=8'd69;
45 : table_value1 <=8'd70; 46 : table_value1 <=8'd72; 47 : table_value1 <=8'd73; 48 : table_value1 <=8'd75; 49 : table_value1 <=8'd76; 50 : table_value1 <=8'd78; 51 : table_value1 <=8'd79; 52 : table_value1 <=8'd81; 53 : table_value1 <=8'd82; 54 : table_value1 <=8'd84; 55 : table_value1 <=8'd85; 56 : table_value1 <=8'd87; 57 : table_value1 <=8'd88; 58 : table_value1 <=8'd90; 59 : table_value1 <=8'd91; 60 : table_value1 <=8'd93; 61 : table_value1 <=8'd94; 62 : table_value1 <=8'd95; 63 : table_value1 <=8'd97; 64 : table_value1 <=8'd98; 65 : table_value1 <=8'd100; 66 : table_value1 <=8'd101; 67 : table_value1 <=8'd103; 68 : table_value1 <=8'd104; 69 : table_value1 <=8'd105; 70 : table_value1 <=8'd107; 71 : table_value1 <=8'd108; 72 : table_value1 <=8'd110; 73 : table_value1 <=8'd111; 74 : table_value1 <=8'd113; 75 : table_value1 <=8'd114; 76 : table_value1 <=8'd115; 77 : table_value1 <=8'd117; 78 : table_value1 <=8'd118; 79 : table_value1 <=8'd120; 80 : table_value1 <=8'd121; 81 : table_value1 <=8'd122; 82 : table_value1 <=8'd124; 83 : table_value1 <=8'd125; 84 : table_value1 <=8'd126; 85 : table_value1 <=8'd128; 86 : table_value1 <=8'd129; 87 : table_value1 <=8'd130; 88 : table_value1 <=8'd132; 89 : table_value1 <=8'd133; 90 : table_value1 <=8'd134; 91 : table_value1 <=8'd136;
92 : table_value1 <=8'd137; 93 : table_value1 <=8'd138; 94 : table_value1 <=8'd140; 95 : table_value1 <=8'd141; 96 : table_value1 <=8'd142; 97 : table_value1 <=8'd144; 98 : table_value1 <=8'd145; 99 : table_value1 <=8'd146; 100 : table_value1 <=8'd147; 101 : table_value1 <=8'd149; 102 : table_value1 <=8'd150; 103 : table_value1 <=8'd151; 104 : table_value1 <=8'd153; 105 : table_value1 <=8'd154; 106 : table_value1 <=8'd155; 107 : table_value1 <=8'd156; 108 : table_value1 <=8'd158; 109 : table_value1 <=8'd159; 110 : table_value1 <=8'd160; 111 : table_value1 <=8'd161; 112 : table_value1 <=8'd162; 113 : table_value1 <=8'd164; 114 : table_value1 <=8'd165; 115 : table_value1 <=8'd166; 116 : table_value1 <=8'd167; 117 : table_value1 <=8'd168; 118 : table_value1 <=8'd170; 119 : table_value1 <=8'd171; 120 : table_value1 <=8'd172; 121 : table_value1 <=8'd173; 122 : table_value1 <=8'd174; 123 : table_value1 <=8'd175; 124 : table_value1 <=8'd176; 125 : table_value1 <=8'd178; 126 : table_value1 <=8'd179; 127 : table_value1 <=8'd180; 128 : table_value1 <=8'd181; 129 : table_value1 <=8'd182; 130 : table_value1 <=8'd183; 131 : table_value1 <=8'd184; 132 : table_value1 <=8'd185; 133 : table_value1 <=8'd186; 134 : table_value1 <=8'd187; 135 : table_value1 <=8'd188; 136 : table_value1 <=8'd189; 137 : table_value1 <=8'd191; 138 : table_value1 <=8'd192;
139 : table_value1 <=8'd193; 140 : table_value1 <=8'd194; 141 : table_value1 <=8'd195; 142 : table_value1 <=8'd196; 143 : table_value1 <=8'd197; 144 : table_value1 <=8'd198; 145 : table_value1 <=8'd199; 146 : table_value1 <=8'd200; 147 : table_value1 <=8'd201; 148 : table_value1 <=8'd202; 149 : table_value1 <=8'd202; 150 : table_value1 <=8'd203; 151 : table_value1 <=8'd204; 152 : table_value1 <=8'd205; 153 : table_value1 <=8'd206; 154 : table_value1 <=8'd207; 155 : table_value1 <=8'd208; 156 : table_value1 <=8'd209; 157 : table_value1 <=8'd210; 158 : table_value1 <=8'd211; 159 : table_value1 <=8'd212; 160 : table_value1 <=8'd212; 161 : table_value1 <=8'd213; 162 : table_value1 <=8'd214; 163 : table_value1 <=8'd215; 164 : table_value1 <=8'd216; 165 : table_value1 <=8'd217; 166 : table_value1 <=8'd218; 167 : table_value1 <=8'd218; 168 : table_value1 <=8'd219; 169 : table_value1 <=8'd220; 170 : table_value1 <=8'd221; 171 : table_value1 <=8'd221; 172 : table_value1 <=8'd222; 173 : table_value1 <=8'd223; 174 : table_value1 <=8'd224; 175 : table_value1 <=8'd225; 176 : table_value1 <=8'd225; 177 : table_value1 <=8'd226; 178 : table_value1 <=8'd227; 179 : table_value1 <=8'd227; 180 : table_value1 <=8'd228; 181 : table_value1 <=8'd229; 182 : table_value1 <=8'd230; 183 : table_value1 <=8'd230; 184 : table_value1 <=8'd231; 185 : table_value1 <=8'd232;
186 : table_value1 <=8'd232; 187 : table_value1 <=8'd233; 188 : table_value1 <=8'd233; 189 : table_value1 <=8'd234; 190 : table_value1 <=8'd235; 191 : table_value1 <=8'd235; 192 : table_value1 <=8'd236; 193 : table_value1 <=8'd236; 194 : table_value1 <=8'd237; 195 : table_value1 <=8'd238; 196 : table_value1 <=8'd238; 197 : table_value1 <=8'd239; 198 : table_value1 <=8'd239; 199 : table_value1 <=8'd240; 200 : table_value1 <=8'd240; 201 : table_value1 <=8'd241; 202 : table_value1 <=8'd241; 203 : table_value1 <=8'd242; 204 : table_value1 <=8'd242; 205 : table_value1 <=8'd243; 206 : table_value1 <=8'd243; 207 : table_value1 <=8'd244; 208 : table_value1 <=8'd244; 209 : table_value1 <=8'd245; 210 : table_value1 <=8'd245; 211 : table_value1 <=8'd246; 212 : table_value1 <=8'd246; 213 : table_value1 <=8'd246; 214 : table_value1 <=8'd247; 215 : table_value1 <=8'd247; 216 : table_value1 <=8'd248; 217 : table_value1 <=8'd248; 218 : table_value1 <=8'd248; 219 : table_value1 <=8'd249; 220 : table_value1 <=8'd249; 221 : table_value1 <=8'd249; 222 : table_value1 <=8'd250; 223 : table_value1 <=8'd250; 224 : table_value1 <=8'd250; 225 : table_value1 <=8'd251; 226 : table_value1 <=8'd251; 227 : table_value1 <=8'd251; 228 : table_value1 <=8'd251; 229 : table_value1 <=8'd252; 230 : table_value1 <=8'd252; 231 : table_value1 <=8'd252; 232 : table_value1 <=8'd252;
233 : table_value1 <=8'd253; 234 : table_value1 <=8'd253; 235 : table_value1 <=8'd253; 236 : table_value1 <=8'd253; 237 : table_value1 <=8'd253; 238 : table_value1 <=8'd254; 239 : table_value1 <=8'd254; 240 : table_value1 <=8'd254; 241 : table_value1 <=8'd254; 242 : table_value1 <=8'd254; 243 : table_value1 <=8'd254; 244 : table_value1 <=8'd254; 245 : table_value1 <=8'd254; 246 : table_value1 <=8'd255; 247 : table_value1 <=8'd255; 248 : table_value1 <=8'd255; 249 : table_value1 <=8'd255; 250 : table_value1 <=8'd255; 251 : table_value1 <=8'd255; 252 : table_value1 <=8'd255; 253 : table_value1 <=8'd255; 254 : table_value1 <=8'd255; 255 : table_value1 <=8'd255; endcase input_2=table_value1; if(index_table1==255 || updown1==1) begin updown1=1; index_table1=index_table1-5; end if(index_table1==0 || updown1==0) begin updown1=0; index_table1=index_table1+5; end end else counter=counter-1; end endmodule