You are on page 1of 87

DSP 101 Part 1: An

Introductory Course in
DSP System Design
by David Skolnick Download PDF

Having heard a lot about digital signal processing (DSP) technology, you may have
wanted to find out what can be done with DSP, investigate why DSP is preferred to
analog circuitry for many types of operations, and discover how to learn enough to
design your own DSP system. This article, the first of a series, is an opportunity to
take a substantial first step towards finding answers to your questions. This series is
an introduction to DSP topics from the point of view of analog system designers
seeking additional tools for handling analog signals. Designers reading this series can
learn about the possibilities of DSP to deal with analog signals and where to find
additional sources of information and assistance.

What is [a] DSP? In brief, DSPs are processors or microcomputers whose hardware,
software, and instruction sets are optimized for high-speed numeric processing
applications an essential for processing digital data representing analog signals in real
time. What a DSP does is straightforward. When acting as a digital filter, for example,
the DSP receives digital values based on samples of a signal, calculates the results of
a filter function operating on these values, and provides digital values that represent
the filter output; it can also provide system control signals based on properties of
these values. The DSP’s high-speed arithmetic and logical hardware is programmed to
rapidly execute algorithms modelling the filter transformation.

The combination of design elements arithmetic operators, memory handling,


instruction set, parallelism, data addressing that provide this ability forms the key
difference between DSPs and other kinds of processors. Understanding the
relationship between real-time signals and DSP calculation speed provides some
background on just how special this combination is. The real-time signal comes to the
DSP as a train of individual samples from an analog-to-digital converter (ADC). To
do filtering in real-time, the DSP must complete all the calculations and operations
required for processing each sample (usually updating a process involving many
previous samples) before the next sample arrives. To perform high-order filtering of
real-world signals having significant frequency content calls for really fast
processors.

Why Use a DSP?


To get an idea of the type of calculations a DSP does and get an idea of how an
analog circuit compares with a DSP system, one could compare the two systems in
terms of a filter function. The familiar analog filter uses resistors, capacitors,
inductors, amplifiers. It can be cheap and easy to assemble, but difficult to calibrate,
modify, and maintain a difficulty that increases exponentially with filter order. For
many purposes, one can more easily design, modify, and depend on filters using a
DSP because the filter function on the DSP is software-based, flexible, and repeatable.
Further, to create flexibly adjustable filters with higher-order response requires only
software modifications, with no additional hardware unlike purely analog circuits. An
ideal bandpass filter, with the frequency response shown in Figure 1, would have the
following characteristics:

 a response within the passband that is completely flat with zero phase shift
 infinite attenuation in the stopband.
Useful additions would include:
 passband tuning and width control
 stopband rolloff control.

As Figure 1 shows, an analog approach using second-order filters would require quite
a few staggered high-Q sections; the difficulty of tuning and adjusting it can be
imagined.

Figure 1. An ideal bandpass filter and


second-order approximations.
With DSP software, there are two basic approaches to filter design: finite impulse
response (FIR) and infinite impulse response (IIR). The FIR filter’s time response to
an impulse is the straightforward weighted sum of the present and a finite number of
previous input samples. Having no feedback, its response to a given sample ends
when the sample reaches the “end of the line” (Figure 2). An FIR filter’s frequency
response has no poles, only zeros. The IIR filter, by comparison, is called infinite
because it is a recursive function: its output is a weighted sum of inputs and outputs.
Since it is recursive, its response can continue indefinitely. An IIR filter frequency
response has both poles and zeros.
Figure 2. Filter equations and delay-line
representation.
The xs are the input samples, ys are the output samples, as are input sample
weightings, and bs are output sample weightings. n is the present sample time,
and M and N are the number of samples programmed (the filter’s order). Note that the
arithmetic operations indicated for both types are simply sums and products in
potentially great number. In fact, multiply-and-add is the case for many DSP
algorithms that represent mathematical operations of great sophistication and
complexity.

Approximating an ideal filter consists of applying a transfer function with appropriate


coefficients and a high enough order, or number of taps (considering the train of input
samples as a tapped delay line). Figure 3 shows the response of a 90-tap FIR filter
compared with sharp-cutoff Chebyshev filters of various orders. The 90-tap example
suggests how close the filter can come to approximating an ideal filter. Within a DSP
system, programming a 90-tap FIR filter like the one in Figure 3 is not a difficult task.
By comparison, it would not be cost-effective to attempt this level of approximation
with a purely analog circuit. Another crucial point in favor of using a DSP to
approximate the ideal filter is long-term stability. With an FIR (or an IIR having
sufficient resolution to avoid truncation-error buildup), the programmable DSP
achieves the same response, time after time. Purely analog filter responses of high
order are less stable with time.

Figure 3. 90-tap FIR filter response compared with


those of sharp cutoff Chebyshev filters.
Mathematical transform theory and practice are the core requirement for creating DSP
applications and understanding their limits. This article series walks through a few
signal-analysis and -processing examples to introduce DSP concepts. The series also
provides references to texts for further study and identifies software tools that ease the
development of signal-processing software.
Sampling Real-World Signals
Real-world phenomena are analog the continuously changing energy levels of
physical processes like sound, light, heat, electricity, magnetism. A transducer
converts these levels into manageable electrical voltage and current signals, and an
ADC samples and converts these signals to digital for processing. The conversion rate,
or sampling frequency, of the ADC is critically important in digital processing of
real-world signals.

This sampling rate is determined by the amount of signal information that is needed
for processing the signals adequately for a given application. In order for an ADC to
provide enough samples to accurately describe the real-world signal, the sampling rate
must be at least twice the highest-frequency component of the analog signal. For
example, to accurately describe an audio signal containing frequencies up to 20 kHz,
the ADC must sample the signal at a minimum of 40 kHz. Since arriving signals can
easily contain component frequencies above 20 kHz (including noise), they must be
removed before sampling by feeding the signal through a low-pass filter ahead of the
ADC. This filter, known as an anti-aliasing filter, is intended to remove the
frequencies above 20 kHz that could corrupt the converted signal.

However, the anti-aliasing filter has a finite frequency rolloff, so additional bandwidth
must be provided for the filter’s transition band. For example, with an input signal
bandwidth of 20 kHz, one might allow 2 to 4 kHz of extra bandwidth.

Figure 4. Antialiasing filter ideal response.


Figure 4 depicts the filter needed to reject any signals with frequencies above half of a
48-kHz sampling rate. Rejection means attenuation to less than 1/2 least-significant
bit (LSB) of the ADC’s resolution. One way to achieve this level of rejection without
a highly sophisticated analog filter is to use an oversamplingconverter, such as a
sigma-delta ADC. It typically obtains low-resolution (e.g., 1-bit) samples at
megahertz rates much faster than twice the highest frequency component greatly
easing the requirement for the analog filter ahead of the converter. An internal digital
filter (DSP at work!) restores the required resolution and frequency response. For
many applications, oversampling converters reduce system design effort and cost.

Processing Real-World Signals


The ADC sampling rate depends on the bandwidth of the analog signal being sampled.
This sampling rate sets the pace at which samples are available for processing. Once
the system bandwidth requirements have established the A/D converter sampling rate,
the designer can begin to explore the speed requirements of the DSP processor.

Processing speed at a required sample rate is influenced by algorithm complexity. As


a rule, the DSP needs to finish all operations relating to the first sample before
receiving the second sample. The time between samples is the time budget for the
DSP to perform all processing tasks. For the audio example, a 48-kHz sampling rate
corresponds to a 20.833-µs sampling interval. Figure 5 relates the analog signal and
digital sampling rate.

Figure 5. Sampling train and processing time.


Next consider the relation between the speed of the DSP and complexity of the
algorithm (the software containing the transform or other set of numeric operations).
Complex algorithms require more processing tasks. Because the time between
samples is fixed, the higher complexity calls for faster processing. For example,
suppose that the algorithm requires 50 processing operations to be performed between
samples. Using the previous example’s 48-kHz sampling rate (20.833-µs sampling
interval), one can calculate the minimum required DSP processor speed, in millions of
operations per second (MOPS) as follows:

Thus if all of the time between samples is available for operations to implement the
algorithm, a processor with a performance level of 2.4 MOPS is required. Note that
the two common ratings for DSPs, based on operations per second (MOPS) and
instructions per second (MIPS), are not the same. A processor with a 10-MIPS rating
that can perform 8 operations per instruction has basically the same performance as a
faster processor with a 40 MIPS rating that can only perform 2 operations per
instruction.

Sampling Various Real-World Signals


There are two basic ways to acquire data, either one sample at a time or one frame at a
time (continuous processing vs. batch processing). Sample-based systems, like a
digital filter, acquire data one sample at a time. As shown in Figure 6, at each tick of
the clock, a sample comes into the system and a processed sample is output. The
output waveform develops continuously.
Figure 6. Example of continuous processing of samples
in digital filter.
Frame-based systems, like a spectrum analyzer, which determines the frequency
components of a time-varying waveform, acquire a frame (or block of samples).
Processing occurs on the entire frame of data and results in a frame of transformed
data, as shown in Figure 7.

Figure 7. Example of batch processing of a block of


data.
For an audio sampling rate of 48 kHz, a processor working on a frame of 1024
samples has a frame acquisition interval of 21.33 ms (i.e., 1024 x 20.833 µs = 21.33
ms). Here the DSP has 21.33 ms to complete all the required processing tasks for that
frame of data. If the system handles signals in real time, it must not lose any data; so
while the DSP is processing the first frame, it must also be acquiring the second frame.
Acquiring the data is one area where special architectural features of DSPs come into
play: Seamless data acquisition is facilitated by a processor’s flexible data-addressing
capabilities in conjunction with its direct memory-accessing (DMA) channels.

Responding to Real-World Signals


One cannot assume that all the time between samples is available for the execution of
processing instructions. In reality, time must be budgeted for the processor to respond
to external devices, controlling the flow of data in and out. Typically, an external
device (such as an ADC) signals the processor using an interrupt. The DSP’s response
time to that interrupt, or interrupt latency, directly influences how much time remains
for actual signal processing.

Interrupt latency (response delay) depends on several factors; the most dominant is
the DSP architecture’s instruction pipelining. An instruction pipeline consists of the
number of instruction cycles that occur between the time an interrupt is received and
the time that program execution resumes. More pipeline levels in a DSP result in
longer interrupt latency. For example, if a processor has a 20-ns cycle time and
requires 10 cycles to respond to an interrupt, 200 ns elapse before it executes any
signal-processing instructions.

When data is acquired one sample at a time, this 200-ns overhead will not hurt if the
DSP finishes the processing of each sample before the next arrives. When data is
acquired sample-by-sample while processing a frame at a time, however, an
interrupted system wastes processor instruction cycles. For example, a system with a
200-ns interrupt response time running a frame-based algorithm, such as the FFT,
with a frame size of 1024 samples, would require 204.8 µs of overhead. That amounts
to more than 10,000 instruction cycles wasted to latency productive time when the
DSP could be performing signal processing. This waste is easy to avoid in DSPs
having architectural features such as DMA and dual memory access; they let the DSP
receive and store data without interrupting the processor.

Developing a DSP System


Having discussed the role of the processor, the ADC, the anti-aliasing filter, and the
timing relationships between these components, it is time to look at a complete DSP
system. Figure 8 shows the building blocks of a typical DSP system that could be
used for data acquisition and control.

Figure 8. Putting together elements of a DSP system.


Note how few components make up the DSP system, because so much of the system’s
functionality comes from the programmable DSP. Converters funnel data into and out
of the DSP; the ADC timing is controlled by a precise sampling clock. To simplify
system design, many converter devices available today combine some or all of the
following: an A/D converter, a D/A converter, a sampling clock, and filters for
anti-aliasing and anti-imaging. The clock oscillator in these types of I/O components
is separately controlled by an external crystal. Here are some important points about
the data flow in this sort of DSP system:

Analog Input: The analog signal is appropriately band-limited by the anti-aliasing


filter and applied to the input of the ADC. At the selected sampling time, the
converter interrupts the DSP processor and makes the digital sample available. The
choice between serial and parallel interfacing between the ADC and DSP depends on
the amount of data, design complexity trade-offs, space, power, and price.

Digital Signal Processing: The incoming data is handled by the DSP’s algorithm
software. When the processor completes the required calculations, it sends the result
to the DAC. Because the signal processing is programmable, considerable flexibility
is available in handling the data and improving system performance with incremental
programming adjustments.

Analog Output: The DAC converts the DSP’s output into the desired analog output
at the next sample clock. The converter’s output is smoothed by a
low-pass, anti-imaging filter (also called a reconstruction filter), to produce the
reconstructed analog signal.

Host Interface: An optional host interface lets the DSP communicate with external
systems, sending and receiving data and control information.

Review and Preview


The goal of this article has been to provide an overview of major DSP design
concepts and explain some of the reasons why a DSP is better suited that analog
circuitry for some applications. The issues introduced in this article include:

 DSP overview
 Real-time DSP operation
 Real-world signals
 Sampling rates and anti-alias filtering
 DSP algorithm time budget
 Sample driven versus frame driven data acquisition

Because these issues involve many valuable levels of detail that we could not do
justice to in this brief article, you should consider reading Richard Higgins’s
text, Digital Signal Processing in VLSI (see References below). This text provides a
complete overview of DSP theory, implementation issues, and reduction to practice
(with devices available at the time it was published), plus exercises and examples.
The Reference section below also contains other sources that further amplify this
article’s issues. To prepare for the next articles in this series, you might want to get
free copies of the ADSP-2100 Family User’s Manual* and the ADSP-2106x SHARC
User’s Manual.* These texts provide information on Analog Devices’s fixed- and
floating-point DSP architectures, a major topic in these articles. The next article will
cover the following territory:

 Mathematical overview of signal processing: It will present the mathematics


for the transform functions (frequency domain) and convolution functions
(time domain) that appear throughout the series. While the mathematical
treatment is necessarily incomplete (no derivations), there will be sufficient
detail for considering how to program the operations.
 DSP architecture: The article will discuss the nature and functioning of the
DSP’s arithmetic-logic unit (ALU), multiply-accumulator (MAC), barrel-shifter,
and memory busses and describe the numeric operations that support DSP
functions.
 DSP programming concepts: A discussion of programming will bring together
theory and practice (math and architecture). Finally, it will lay out the main
parameters for a series-length DSP design project, provided as an example.
DSP 101 Parte 1: Um
Curso Introdutório de
Design de Sistemas DSP
de David Skolnick baixar PDF

Tendo ouvido muito sobre a tecnologia de processamento digital de sinais (DSP),


você pode querer descobrir o que pode ser feito com o DSP, investigar por que o DSP
é preferido ao circuito analógico para muitos tipos de operações e descobrir como
aprender o suficiente para projetar próprio sistema DSP. Este artigo, o primeiro de
uma série, é uma oportunidade para dar um primeiro passo importante para encontrar
respostas às suas perguntas. Esta série é uma introdução aos tópicos de DSP do ponto
de vista de projetistas de sistemas analógicos que buscam ferramentas adicionais para
lidar com sinais analógicos. Designers que leem esta série podem aprender sobre as
possibilidades do DSP lidar com sinais analógicos e onde encontrar fontes adicionais
de informação e assistência.

O que é um DSP? Em resumo, os DSPs são processadores ou microcomputadores


cujos conjuntos de hardware, software e instruções são otimizados para aplicativos de
processamento numérico de alta velocidade. um essencial para o processamento de
dados digitais que representam sinais analógicos em tempo real. O que um DSP faz é
simples. Ao agir como um filtro digital, por exemplo, o DSP recebe valores digitais
baseados em amostras de um sinal, calcula os resultados de uma função de filtro que
opera nesses valores e fornece valores digitais que representam a saída do filtro; Ele
também pode fornecer sinais de controle do sistema com base nas propriedades desses
valores. O hardware aritmético e lógico de alta velocidade do DSP é programado para
executar rapidamente algoritmos que modelam a transformação de filtro.

A combinação de elementos de design operadores aritméticos, manipulação de


memória, conjunto de instruções, paralelismo, endereçamento de dados que fornecem
essa habilidade forma a diferença chave entre os DSPs e outros tipos de
processadores. Compreender a relação entre os sinais em tempo real e a velocidade de
cálculo do DSP fornece algumas informações sobre quão especial é essa
combinação. O sinal em tempo real chega ao DSP como um trem de amostras
individuais de um conversor analógico-digital (ADC). Para fazer a filtragem em
tempo real, o DSP deve concluir todos os cálculos e operações necessários para
processar cada amostra (geralmente atualizando um processo que envolve muitas
amostras anteriores) antes da próxima amostra chegar. Para realizar a filtragem de alta
ordem de sinais do mundo real, ter conteúdo de frequência significativo exige
processadores realmente rápidos.

Por que usar um DSP?


Para se ter uma ideia do tipo de cálculos que um DSP faz e ter uma ideia de como um
circuito analógico se compara com um sistema DSP, pode-se comparar os dois
sistemas em termos de uma função de filtro. O filtro analógico familiar usa resistores,
capacitores, indutores, amplificadores. Pode ser barato e fácil de montar, mas difícil
de calibrar, modificar e manter uma dificuldade que aumenta exponencialmente com
a ordem do filtro. Para muitos propósitos, é mais fácil projetar, modificar e depender
de filtros usando um DSP, porque a função de filtro no DSP é baseada em software,
flexível e repetível. Além disso, para criar filtros flexíveis e ajustáveis com
resposta de ordem superior, é necessário apenas modificações de software, sem
hardware adicional ao contrário de circuitos puramente analógicos. Um filtro de
passagem de banda ideal, com a resposta de frequência mostrada na Figura 1, teria as
seguintes características:

 uma resposta dentro da banda passante que é completamente plana com


deslocamento de fase zero
 atenuação infinita no stopband.
Adições úteis incluem:
 ajuste de banda passante e controle de largura
 controle de rolagem de stopband.
Como mostra a Figura 1, uma abordagem analógica usando filtros de segunda ordem
exigiria algumas poucas seções high-Q escalonadas; a dificuldade de sintonizar e
ajustar pode ser imaginada.

Figura 1. Um filtro de passagem de banda ideal


e aproximações de segunda ordem.

Com o software DSP, existem duas abordagens básicas para o design do


filtro: finito resposta ao impulso (FIR) e infinito resposta ao impulso (IIR). A
resposta temporal do filtro FIR a um impulso é a soma ponderada direta do presente e
uma finito número de amostras de entrada anteriores. Não tendo feedback, sua
resposta a uma dada amostra termina quando a amostra atinge o “fim da linha”
(Figura 2). A resposta de freqüência de um filtro FIR não tem pólos, apenas zeros. O
filtro IIR, por comparação, é chamado de infinito porque é uma função recursiva: sua
saída é uma soma ponderada de entradas e saídas. Como é recursivo, sua resposta
pode continuar indefinidamente. Uma resposta de freqüência do filtro IIR tem os dois
polos e zeros.
Figura 2. Equações de filtro e
representação da linha de atraso.

o x s são as amostras de entrada, y s são as amostras de saída, a s são pesos


amostrais de entrada e b s são pesos de amostra da saída. n é o tempo de
amostragem atual e M e N são o número de amostras programadas (o filtro
é ordem ). Note que as operações aritméticas indicadas para ambos os tipos são
simplesmente somas e produtos em número potencialmente grande. Na verdade,
multiplicar e adicionar é o caso de muitos algoritmos DSP que representam operações
matemáticas de grande sofisticação e complexidade.

A aproximação de um filtro ideal consiste em aplicar uma função de transferência


com coeficientes apropriados e uma ordem suficientemente alta, ou número
de torneiras (considerando o trem de amostras de entrada como uma linha de atraso
derivado). A Figura 3 mostra a resposta de um filtro FIR de 90 derivações em
comparação com filtros Chebyshev de corte cortante de várias ordens. O exemplo de
90 derivações sugere o quão próximo o filtro pode aproximar-se de um filtro
ideal. Dentro de um sistema DSP, programar um filtro FIR de 90 derivações como o
da Figura 3 não é uma tarefa difícil. Por comparação, não seria rentável tentar esse
nível de aproximação com um circuito puramente analógico. Outro ponto crucial a
favor do uso de um DSP para aproximar o filtro ideal é a estabilidade a longo
prazo. Com um FIR (ou um IIR com resolução suficiente para evitar o acúmulo de
erros de truncamento), o DSP programável obtém a mesma resposta, uma e outra
vez. Respostas de filtro puramente analógicas de alta ordem são menos estáveis
com o tempo.

Figura 3. Resposta do filtro FIR de 90 derivações


em comparação com os filtros Chebyshev de corte agudo.

A teoria e a prática da transformação matemática são o requisito básico para criar


aplicativos DSP e entender seus limites. Esta série de artigos analisa alguns exemplos
de análise e processamento de sinais para apresentar os conceitos de DSP. A série
também fornece referências a textos para estudos futuros e identifica ferramentas de
software que facilitam o desenvolvimento de software de processamento de sinais.

Amostragem de Sinais do Mundo Real


Fenômenos do mundo real são analógicos os níveis de energia em constante mudança
de processos físicos como som, luz, calor, eletricidade, magnetismo. Um transdutor
converte esses níveis em sinais de corrente e tensão elétrica gerenciáveis, e um ADC
faz a amostragem e converte esses sinais. sinais para digital para processamento. A
taxa de conversão, ou frequência de amostragem, do ADC é criticamente importante
no processamento digital de sinais do mundo real.

Esta taxa de amostragem é determinada pela quantidade de informação de sinal que é


necessária para processar os sinais adequadamente para uma dada aplicação. Para que
um ADC forneça amostras suficientes para descrever com precisão o sinal do mundo
real, a taxa de amostragem deve ser pelo menos o dobro do componente de maior
frequência do sinal analógico. Por exemplo, para descrever com precisão um sinal de
áudio contendo freqüências de até 20 kHz, o ADC deve amostrar o sinal com um
mínimo de 40 kHz. Como os sinais que chegam podem conter facilmente freqüências
componentes acima de 20 kHz (incluindo ruído), eles devem ser removidos antes da
amostragem, alimentando o sinal através de um filtro passa-baixo à frente do
ADC. Este filtro, conhecido como anti-aliasing filtro, destina-se a remover as
frequências acima de 20 kHz que podem corromper o sinal convertido.

No entanto, o filtro de anti-aliasing tem um rolloff de frequência finito, portanto, deve


ser fornecida largura de banda adicional para a banda de transição do filtro. Por
exemplo, com uma largura de banda de sinal de entrada de 20 kHz, pode-se permitir
de 2 a 4 kHz de largura de banda extra.

Figura 4. Resposta ideal do filtro antialiasing.

A Figura 4 mostra o filtro necessário para rejeitar quaisquer sinais com frequências
acima da metade de uma taxa de amostragem de 48 kHz. Rejeição significa
atenuação para menos de 1/2 bit menos significativo (LSB) da resolução do
ADC. Uma maneira de alcançar este nível de rejeição sem um filtro analógico
altamente sofisticado é usar um conversor de oversampling , como um ADC
sigma-delta.Normalmente obtém amostras de baixa resolução (por exemplo, 1 bit) em
taxas de megahertz muito mais rápido que o dobro do componente de maior
freqüência facilitando bastante a necessidade do filtro analógico à frente do
conversor. Um filtro digital interno (DSP no trabalho!) Restaura a resolução e a
resposta de frequência necessárias. Para muitas aplicações, os conversores de
oversampling reduzem o esforço e o custo do projeto do sistema.

Processando Sinais do Mundo Real


A taxa de amostragem do ADC depende da largura de banda do sinal analógico que
está sendo amostrado. Essa taxa de amostragem define o ritmo em que as amostras
estão disponíveis para processamento.Uma vez que os requisitos de largura de banda
do sistema tenham estabelecido a taxa de amostragem do conversor A / D, o projetista
pode começar a explorar os requisitos de velocidade do processador DSP.

A velocidade de processamento em uma taxa de amostragem exigida é influenciada


pela complexidade do algoritmo. Como regra geral, o DSP precisa concluir todas as
operações relacionadas à primeira amostra antes de receber a segunda amostra. O
tempo entre as amostras é o orçamento de tempo do DSP para executar todas as
tarefas de processamento. Para o exemplo de áudio, uma taxa de amostragem de 48
kHz corresponde a um intervalo de amostragem de 20,833-µs. A Figura 5 relaciona o
sinal analógico e a taxa de amostragem digital.

Figura 5. Trem de amostragem e tempo de


processamento.

Em seguida, considere a relação entre a velocidade do DSP e a complexidade do


algoritmo (o software que contém a transformação ou outro conjunto de operações
numéricas). Algoritmos complexos requerem mais tarefas de processamento. Como o
tempo entre as amostras é fixo, a maior complexidade exige um processamento mais
rápido. Por exemplo, suponha que o algoritmo exija que 50 operações de
processamento sejam realizadas entre as amostras. Usando a taxa de amostragem de
48 kHz do exemplo anterior (intervalo de amostragem de 20,833-µs), pode-se calcular
a velocidade mínima necessária do processador DSP, em milhões de operações por
segundo (MOPS), como segue:

Assim, se todo o tempo entre amostras estiver disponível para operações para
implementar o algoritmo, será necessário um processador com um nível de
desempenho de 2,4 MOPS. Observe que as duas classificações comuns para DSPs,
baseadas em operações por segundo (MOPS) e instruções por segundo (MIPS), não
são as mesmas. Um processador com uma classificação de 10-MIPS que pode
executar 8 operações por instrução tem basicamente o mesmo desempenho que um
processador mais rápido com uma classificação de 40 MIPS que pode realizar apenas
2 operações por instrução.
Amostragem de vários sinais do mundo real
Há duas maneiras básicas de adquirir dados, uma amostra por vez ou um quadro por
vez (processamento contínuo versus processamento em lote). Os sistemas baseados
em amostras, como um filtro digital, adquirem dados uma amostra por vez. Como
mostrado na Figura 6, a cada tick do relógio, uma amostra entra no sistema e uma
amostra processada é enviada. A forma de onda de saída se desenvolve
continuamente.

Figura 6. Exemplo de processamento contínuo de


amostras no filtro digital.

Sistemas baseados em quadros, como um analisador de espectro, que determina os


componentes de frequência de uma forma de onda variável no tempo, adquirem um
quadro (ou bloco de amostras). O processamento ocorre em todo o quadro de dados e
resulta em um quadro de dados transformados, conforme mostrado na Figura 7.

Figura 7. Exemplo de processamento em lote de um bloco


de dados.

Para uma taxa de amostragem de áudio de 48 kHz, um processador trabalhando em


um quadro de 1024 amostras possui um intervalo de aquisição de quadros de 21,33
ms (isto é, 1024 x 20,833 µs = 21,33 ms). Aqui, o DSP tem 21,33 ms para concluir
todas as tarefas de processamento necessárias para esse quadro de dados. Se o sistema
manejar sinais em tempo real, não deve perder nenhum dado; Assim, enquanto o DSP
está processando o primeiro quadro, ele também deve estar adquirindo o segundo
quadro. Adquirir os dados é uma área em que as características arquitetônicas
especiais dos DSPs entram em ação: A aquisição de dados contínua é facilitada pelos
recursos flexíveis de endereçamento de dados de um processador em conjunto com
seus canais de acesso direto à memória (DMA).

Respondendo a sinais do mundo real


Não se pode supor que todo o tempo entre amostras esteja disponível para a execução
de instruções de processamento. Na realidade, o tempo deve ser orçado para o
processador responder a dispositivos externos, controlando o fluxo de entrada e saída
de dados. Normalmente, um dispositivo externo (como um ADC) sinaliza o
processador usando uma interrupção. O tempo de resposta do DSP a essa interrupção
ou latência de interrupção , influencia diretamente quanto tempo resta para o
processamento real do sinal.
A latência de interrupção (atraso de resposta) depende de vários fatores; o mais
dominante é o pipelining de instruções da arquitetura DSP. Um pipeline de instruções
consiste no número de ciclos de instruções que ocorrem entre o momento em que uma
interrupção é recebida e o momento em que a execução do programa é
retomada. Mais níveis de pipeline em um DSP resultam em maior latência de
interrupção. Por exemplo, se um processador tiver um tempo de ciclo de 20 ns e
precisar de 10 ciclos para responder a uma interrupção, decorrem 200 ns antes de
executar qualquer instrução de processamento de sinal.

Quando os dados são adquiridos uma amostra de cada vez, essa sobrecarga de 200 ns
não irá prejudicar se o DSP terminar o processamento de cada amostra antes da
próxima chegar. Quando os dados são adquiridos amostra por amostra ao processar
um quadro de cada vez, no entanto, um sistema interrompido desperdiça ciclos de
instrução do processador. Por exemplo, um sistema com um tempo de resposta de
interrupção de 200 ns executando um algoritmo baseado em quadros, como o FFT,
com um tamanho de quadro de 1024 amostras, exigiria 204,8 µs de sobrecarga. Isso
equivale a mais de 10.000 ciclos de instrução desperdiçados em latência tempo
produtivo quando o DSP poderia estar executando o processamento de sinal. Esse
desperdício é fácil de evitar em DSPs com recursos de arquitetura, como DMA e
acesso de memória dupla; eles permitem que o DSP receba e armazene dados sem
interromper o processador.

Desenvolvendo um sistema DSP


Tendo discutido o papel do processador, o ADC, o filtro anti-aliasing e as relações de
tempo entre esses componentes, é hora de olhar para um sistema DSP completo. A
Figura 8 mostra os blocos de construção de um sistema DSP típico que pode ser usado
para aquisição e controle de dados.

Figura 8. Colocando juntos elementos de um sistema DSP.

Observe como poucos componentes compõem o sistema DSP, porque grande parte da
funcionalidade do sistema vem do DSP programável. Os conversores canalizam os
dados para dentro e fora do DSP; o tempo do ADC é controlado por um relógio de
amostragem preciso. Para simplificar o design do sistema, muitos dispositivos
conversores disponíveis atualmente combinam alguns ou todos os seguintes: um
conversor A / D, um conversor D / A, um relógio de amostragem e filtros para
anti-aliasing e anti-imaging. O oscilador de clock nesses tipos de componentes de E /
S é controlado separadamente por um cristal externo. Aqui estão alguns pontos
importantes sobre o fluxo de dados nesse tipo de sistema DSP:

Entrada analógica: O sinal analógico é apropriadamente limitado à banda pelo


filtro anti-aliasing e aplicado à entrada do ADC. No momento da amostragem
selecionada, o conversor interrompe o processador DSP e disponibiliza a amostra
digital. A escolha entre a interface serial e paralela entre o ADC e o DSP depende da
quantidade de dados, das compensações de complexidade do projeto, do espaço, da
potência e do preço.

Processamento de sinal digital: Os dados recebidos são manipulados pelo software


de algoritmo do DSP. Quando o processador conclui os cálculos necessários, ele envia
o resultado para o DAC. Como o processamento do sinal é programável, uma
flexibilidade considerável está disponível no manuseio dos dados e na melhoria do
desempenho do sistema com ajustes incrementais de programação.

Saída Analógica: O DAC converte a saída do DSP na saída analógica desejada no


próximo relógio de amostra. A saída do conversor é suavizada por um
passa-baixa, anti-imagem filtro (também chamado de filtro de reconstrução), para
produzir o sinal analógico reconstruído.

Interface do Host: Uma interface de host opcional permite que o DSP se


comunique com sistemas externos, enviando e recebendo dados e informações de
controle.

Revise e visualize
O objetivo deste artigo foi fornecer uma visão geral dos principais conceitos de design
de DSP e explicar algumas das razões pelas quais um DSP é mais adequado para
circuitos analógicos para algumas aplicações. Os problemas introduzidos neste artigo
incluem:

 Visão geral do DSP


 Operação DSP em tempo real
 Sinais do mundo real
 Taxas de amostragem e filtragem de anti-alias
 Orçamento de tempo do algoritmo DSP
 Captação de dados conduzida por amostra versus acionada por quadro
Como essas questões envolvem muitos níveis valiosos de detalhes que não
poderíamos fazer justiça neste breve artigo, você deve considerar a leitura do texto de
Richard Higgins, Processamento Digital de Sinais no VLSI (ver referências
abaixo). Este texto fornece uma visão geral completa da teoria DSP, problemas de
implementação e redução à prática (com dispositivos disponíveis no momento em que
foi publicado), além de exercícios e exemplos. A seção de referência abaixo também
contém outras fontes que amplificam ainda mais os problemas deste artigo. Para se
preparar para os próximos artigos desta série, talvez você queira obter cópias gratuitas
do Manual do Usuário da Família ADSP-2100 * e o Manual do Usuário do
ADSP-2106x SHARC. * Esses textos fornecem informações sobre as arquiteturas
DSP fixas e flutuantes da Analog Devices, um tópico importante nesses artigos. O
próximo artigo abrangerá o seguinte território:

 Visão geral matemática do processamento de sinal: Ele apresentará a


matemática para as funções de transformação (domínio da frequência) e
funções de convolução (domínio do tempo) que aparecem ao longo da
série. Enquanto o tratamento matemático é necessariamente incompleto (sem
derivações), haverá detalhes suficientes para considerar como programar as
operações.
 Arquitetura DSP: O artigo discutirá a natureza e o funcionamento da
unidade lógica aritmética (ALU), multiplexador-acumulador (MAC), barril-shifter
e barramento de memória do DSP. e descrever as operações numéricas que
suportam funções DSP.
 Conceitos de programação DSP: Uma discussão de programação reunirá
teoria e prática (matemática e arquitetura). Finalmente, serão apresentados os
principais parâmetros para um projeto de projeto de DSP em série, fornecido
como exemplo.

Why use a DSP? [Digital


Signal Processing
101-An Introductory
Course in DSP System
Design-Part 2]
by David Skolnick and Noam Levine Download PDF

If you've read Part 1 of this series (or are already familiar with some of the ways a
DSP can work with real-world signals), you might want to learn more about how
digital filters (such as those described in Part 1) can be implemented with a DSP.This
article, the second of a series, introduces the following DSP topics:

 Modeling filter transform functions


 Relating the models to DSP architecture
 Experimenting with digital filters

This series seeks to describe these topics from the perspective of analog system
designers who want to add DSP to their design repertoire. Using the information from
articles in this series as an introduction, designers can make more informed decisions
about when DSP designs might be more productive than analog circuits.

Modeling Filter Transform Functions


Part 1 compared analog and digital filter properties and suggested why one might
implement these filters digitally (using DSP); this part focuses on some of the
mechanics of digital filter application.

The three principal reasons for using digital filtering are (1) closer approach to ideal
filter approximations, (2) ability to adjust filter characteristics in software rather than
by physical tuning, and (3) compatibility of filter response with sampled data. The
two best-known filters described in Part 1 are the finite impulse-response (FIR) and
infinite impulse-response (IIR) types. The FIR filter response is called finite because
its output is based solely on a finite set of input samples; it is non-recursive and has
no poles, only zeroes in its s-plane.The IIR filter, on the other hand, has a response
that can go on indefinitely (and can be unstable) because it is recursive, i.e., its output
values are affected by both input and output. It has both poles and zeroes in its s-plane.
Figure 1 shows the typical filter architectures and summation formulas that appeared
in Part 1.

Figure 1. Filter equations and their


delay-line models.
To model these filters digitally, one might take two steps. First, view these formulas
as programs running on a computer. This step consists of breaking down the formula
into the mathematical steps (e.g., multiply and add) and identifying all of the
additional operations that would be necessary for a computer to perform (handling
instructions and data, testing status, etc.) to implement the formula in software.

Second, take those operations and write them as a program.This can be a fairly
arduous task. Fortunately, there is much "canned" software available, often in a
high-level language (HLL) such as C, somewhat simplifying (but by no means
eliminating!) the job of programming. From the point of view of learning, though, it
may be more instructive to start with assembly language; also assembly language
algorithms are often more useful than HLL where system performance must be
optimized. At the level of abstraction of some high-level languages, the program may
not look much like the equations. For example, Figure 2 shows an example of an FIR
algorithm implemented as a C program.*

float fir_filter(float input, float *coef, int n, float *history)


{
int i;
float *hist_ptr, *hist1_ptr, *coef_ptr;
float output;
hist_ptr = history;
hist1_ptr = hist_ptr; /* use for history update */
coef_ptr = coef + n -1; /* point to last coef */
/*form output accumulation */
output = *hist_ptr++ * (*coef_ptr-);
for(i = 2; i < n; i++)
{
*hist1_ptr++ = *hist_ptr; /* update history array */
output += (*hist_ptr++) * (*coef_ptr-);
}
output += input * (*coef_ptr); /* input tap */
*hist1_ptr = input; /* last history */
return(output);
}

Figure 2. FIR Filter as C program.

There are many analysis packages available that support algorithm modeling; see the
references at the end of this article for several popular packages.We will return to
algorithm modeling at various times in the course of this series. Now, continuing the
discussion of the process, after these filter algorithms have been modeled, they are
ready for implementation in DSP architecture.

Relating The Models To DSP Architecture: For programming, one must understand
four sections of DSP architecture: numeric, memory, sequencer, and I/O operations.
This architectural discussion is generic (applying to general DSP concepts), but it is
also specific as it relates to programming examples later in this article. Figure 3 shows
the generalized DSP architecture that this section describes.

Architecture
Numeric Section: Because DSPs must complete multiply/accumulate, add, subtract,
and/or bit-shift operations in a single instruction cycle, hardware optimized for
numeric operations is central to all DSP processors. It is this hardware that
distinguishes DSPs from general-purpose microprocessors, which can require many
cycles to complete these types of operations. In the digital filters (and other DSP
algorithms), the DSP must complete multiple steps of arithmetic operations involving
data values and coefficients, to produce responses in real time that have not been
possible with general-purpose processors.

Numeric operations occur within a DSP's multiply/accumulator (MAC),


arithmetic-logic unit (ALU), and barrel shifter (shifter). The MAC performs
sum-of-products operations, which appear in most DSP algorithms (such as FIR and
IIR filters and fast Fourier transforms). ALU capabilities include addition, subtraction,
and logical operations. Operations on bits and words occur within the shifter. Figure 3
shows the parallelism of the MAC, ALU, and shifter and how data can flow into and
out of them.
Figure 3. A useful DSP architecture.
From a programming point of view, a DSP architecture that uses separate numeric
sections provides great flexibility and efficiency. There are many non-conflicting
paths for data, allowing single-cycle completion of numeric operations. The
architecture of the DSP must also provide a wide dynamic range for MAC operations,
with the ability to handle multiplication results that are double the width of the
inputs-and accumulator outputs that can mount up without overflowing. (On a 16-bit
DSP, this feature equates to 16-bit data inputs and a 40-bit result output from the
MAC.) One needs this range for handling most DSP algorithms (such as filters).

Other features of the numeric section can facilitate programming in real-time systems.
By making operations contingent on a variety of conditional states, which result from
numeric operations, these can serve as variables in a program's execution, testing for
carries, overflows, saturates, flags, or other states. Using these conditionals, a DSP
can rapidly handle decisions about program flow based on numeric operations. The
need to be constantly feeding data into the numeric section is a key design influence
on the DSP's memory and internal bus structures.

Memory Section: DSP memory and bus architecture design is guided by the need for
speed. Data and instructions must flow into the numeric and sequencing sections of
the DSP on every instruction cycle. There can be no delays, no bottlenecks.
Everything about the design focuses on throughput.

Etymology of Harvard and von Neumann Architectures- According to John A. N.


Lee, Department of Computer Science, Virginia Tech:

"Howard Aiken, developer of the Harvard series of machines, insisted on the


separation of data and programs in all his machines. In the Mark III, which I know
best, he even had different size drums for each."

"The von Neumann concept was that by treating instructions as data one could make
alterations in programs, enhancing the ability for programs to 'learn'."

"For some reason, the latter was given von Neumann's name, while the former took its
name from the Harvard line of machines."

To put this focus on throughput in perspective, one can look at the difference between
DSP memory design and memory for other microprocessors. Most microprocessors
use a single memory space containing both data and instructions, using one bus for
address and other for data or instructions. This architecture is called von Neumann
architecture. The limitation on throughput in a von Neumann architecture comes from
having to choose between either a piece of data or an instruction on each cycle. In
DSPs, memory is typically divided into program and data memory-with separate
busses for each. This type of architecture is referred to as Harvard architecture. By
separating the data and instructions, the DSP can fetch multiple items on each cycle,
doubling throughput. Additional optimizations, such as instruction cache, results
feedback, and context switching also increase DSP throughput.

Other optimizations in DSP memory architecture relate to repeated memory accesses.


Most DSP algorithms, such as digital filters, need to get data from memory in a
repeating pattern of accesses. Typically, this type of access serves to fetch data from a
range of addresses, a range that is filled with data from the real-world signals to be
processed. By reducing the number of instructions needed to "manage" memory
accesses (overhead), DSPs "save" instruction cycles, allowing more time for the main
job of each cycle-processing signals. To reduce overhead and automatically manage
these types of accesses, DSPs utilize specialized data address-generators (DAGs).

Most DSP algorithms require two operands to be fetched from memory in a single
cycle to become inputs to the arithmetic units. To supply the addresses of these two
operands in a flexible manner, the DSP has two DAGs. In the DSP's modified
Harvard architecture, one address generator supplies an address over the data-memory
address bus; the other supplies an address over the program-memory address bus. By
performing these two data fetches in time for the next numeric instruction, the DSP is
able to sustain single-cycle execution of instructions.

DSP algorithms, such as the example digital filters, usually require data in a range of
addresses (a buffer) to be addressed so that the address pointer "wraps-around" from
the end of the buffer back to the start of the buffer (buffer length). This pointer
movement is called circular buffering. (In the filter equations, each summation
basically results from a sequence of multiply-and-accumulates of a circular buffer of
data points and a circular buffer of coefficients). A variation of circular buffering,
which is required in some applications, advances the address pointer by values greater
than one address per "step," but still wraps around at a given length. This variation is
called modulo circular buffering.

By supporting various types of buffering with its DAGs, the DSP is able to perform
address modify and compare operations in hardware for optimum efficiency.
Performing these functions in software (as occurs in general purpose processors)
limits the processor's ability to handle real-time signals.

Because buffering is an unusual concept, yet key to digital signal processing, a brief
buffering example is useful. In the example illustrated in Figure 4, a buffer of eight
locations resides in memory starting at address 30. The address generator must
calculate next addresses that stay within this buffer yet keep the proper data spacing
so that two locations are skipped. The address generator outputs the address 30 on to
the address bus while it modifies the address to 33 for the next cycle's memory access.
This process repeats, moving the address pointer through the buffer. A special case
occurs when the address 36 gets modified to 39. The address 39 is outside the buffer.
The address generator detects that the address has fallen outside of the buffer
boundary and modifies the address to 31 as if the end of the buffer is connected to the
start of the buffer. The update, compare, and modify occur with no overhead. In one
cycle, the address 36 is output onto the address bus. On the next cycle, the address 31
is output onto the address bus. This modulo circular buffering serves the needs of
algorithms such as interpolation filters and saves instruction cycles for processing.

Figure 4.Example of
modulo circular buffering.
Sequencer Section: Because most DSP algorithms (such as the example filters) are
by nature repetitive, the DSP's program sequencer needs to loop through the repeated
code without incurring overhead while getting from the end of the loop back to the
start of the loop. This capability is called zero-overhead looping. Having the ability to
loop without overhead is a key area in which DSPs differ from conventional
microprocessors. Typically, microprocessors require that program loops be
maintained in software, placing a conditional instruction at the end of the loop. This
conditional instruction determines whether the address pointer moves (jumps) back to
the top of the loop or to another address. Because getting these addresses from
memory takes time- and availability of time for signal-processing is critical in DSP
applications-DSPs cannot waste cycles retrieving addresses for conditional program
sequencing (branching) in this manner. Instead, DSPs perform these test and branch
functions in hardware, storing the needed addresses.

As Figure 5 shows, the DSP executes the last instruction of the loop in one cycle. On
the next cycle, the DSP evaluates the conditional and executes either the first
instruction at the top of the loop or the first instruction outside the loop. Because the
DSP uses dedicated hardware for these operations, no extra time is wasted with
software evaluating conditionals, retrieving addresses, or branching program
execution.
Figure 5.
Example of program loop.
Input/Output (I/O) Section: As noted again and again, there is a need for
tremendous throughput of data to the DSP; everything about its design is focused on
funneling data into and out of the numeric, memory, and sequencer sections. The
source of the data- and destination of the output (the result of signal processing)-is the
DSP's connection to its system and the real-world. A number of I/O functions are
required to complete signal processing tasks. Off-DSP memory arrays store processor
instructions and data. Communication channels (such as serial ports, I/O ports and
direct memory accessing (DMA) channels transfer data into and out of the DSP
quickly. Other functions (such as timers and program boot logic) ease DSP system
development. A brief list of typical I/O tasks in a DSP system includes the following
(among many others):

 Boot loading: At Reset, the DSP loads instructions form an external source
(EPROM or host) usually through an external memory interface.
 Serial communications: The DSP receives or transmits data through a
synchronous serial port (SPORT), communicating with codecs, ADCs, DACs, or
other devices.
 Memory-mapped I/O: The DSP receives or transmits data through an off-DSP
memory location that is decoded by an external device.

Experimenting with Digital Filters


Having modeled the filter algorithms and looked at some of the DSP architectural
features, one is ready to start looking at how these filters could be coded in DSP
assembly language. Up to this point the discussion and examples have been generic,
applying to almost all DSPs. Here, the example is specific to the Analog Devices
ADSP-2181. This processor is a fixed-point, 16-bit DSP. The term "fixed-point"
means that the "point" separating the mantissa and exponent does not change its bit
location during arithmetic operations. Fixed-point DSPs can be more challenging to
program, but they tend to be less expensive than floating-point DSPs. The "16-bit" in
"16-bit DSP" refers to the size of the DSP's data words. This DSP uses 16-bit data
words and 24-bit wide instruction words. DSPs are specified by the size of the data,
rather than instruction width because data word size describes the width of data that
the DSP can handle most efficiently.
The example program in Figure 6 is an FIR filter in ADSP-2181 assembly language.
The software has two parts. The main routine includes register and buffer
initialization along with the interrupt vector table, and the interrupt routine that
executes when a data sample is ready. After initialization, the DSP executes
instructions in the main routine, performing some background tasks, looping through
code, or idling in a low-power standby mode until it gets an interrupt from the A/D
converter. In this example, the processor idles in a low-power standby mode waiting
for an interrupt.

The FIR filter interrupt subroutine (the last segment of code) is the heart of the filter
program. The processor responds to the interrupt, saving the context of the main
routine and jumping to the interrupt routine. This interrupt routine processes the filter
input sample, reading data and filter coefficients from memory and storing them in
data registers of the DSP processor. After processing the input sample, the DSP sends
an output sample to the D/A converter.

.module/RAM/ABS=0 FIR_PROGRAM;
/******** Initialize Constants and Variables *****************/
.const taps=127;
.var/dm/circ data[taps];
.var/pm/circ fir_coefs[taps];
.init fir_coefs: ;
.var/dm/circ output_data[taps];
/******** Interrupt vector table *****************************/
reset_svc: jump start; rti; rti; rti;
/*00: reset */
irq2_svc: /*04: IRQ2 */
si=io(0); /* get next sample */
dm(i0,m0)=si; /* store in tap delay line */
jump fir; /* jump to fir filter */
nop; /* nop is placeholder */
irql1_svc: rti; rti; rti; rti; /*08: IRQL1 */
irql0_svc: rti; rti; rti; rti; /*0c: IRQL0 */
sp0tx_svc: rti; rti; rti; rti; /*10: SPORT0 tx */
sp0rx_svc: rti; rti; rti; rti; /*14: SPORT1 rx */
irqe_svc: rti; rti; rti; rti; /*18: IRQE */
bdma_svc: rti; rti; rti; rti; /*1c: BDMA */
sp1tx_svc: rti; rti; rti; rti; /*20: SPORT1 tx or IRQ1 */
sp1rx_svc: rti; rti; rti; rti; /*24: SPORT1 rx or IRQ0 */
timer_svc: rti; rti; rti; rti; /*28: timer */
pwdn_svc: rti; rti; rti; rti; /*2c: power down */
/******* START OF PROGRAM - initialize mask, pointers **********/
start:
/* set up various control registers */
ICNTL=0x07; /* set IRQ2, IRQ1, IRQ0 edge sensitive */
IFC=0xFF; /* clear all pending interrupts */
NOP; /* add nop because of one cycle */
/* synchronization delay of IFC */
SI=0x0000;
DM(0x3FFF)=SI; /* sports not enabled */
/* sport1 set for IRQ1, IRQ0, FI, FO */
IMASK=0x200; /* enable IRQ2 interrupt */
i0=^data; /* index to data buffer */
l0=taps; /* length of data buffer */
m0=1; /* post modify value */
i4=^fir_coefs; /* index to fir_coefs buffer */
l4=taps; /* length of fir_coefs buffer */
m4=1; /* post modify value */
i2=^output_data; /* index to data buffer */
l2=taps; /* length of data buffer */
cntr=taps;
do zero until ce;
dm(i0,m0)=0; /* clear out the tap delay data buffer */
zero: dm(i2,m0)=0; /* clear out the output_data buffer */
/**** WAIT for IRQ2 Interrupt - then JUMP to INTERRUPT VECTOR **/
wait: idle; /* wait for IRQ2 interrupt */
jump wait;
/******* FIR FILTER interrupt subroutine ***********************/
fir cntr=taps-1; /* set up loop counter */
mr=0, mx0=dm(i0,m0), my0=pm(i4,m4);
/* fetch data and coefficient */
do fir1loop until ce; /* set up loop */
fir1loop: mr=mr+mx0*my0(ss), mx0=dm(i0,m0), my0=pm(i4,m4);
/* calculations */
/* if not ce jump fir1loop;*/
mr=mr+mx0*my0(rnd); /* round final result to 16-bits */
if mv sat mr; /* if overflow, saturate */
io(1)=mr1; /* send result to DAC */
dm(i2,m0)=mr1;
rti;
/******* END OF PROGRAM *************************************/
.endmod;

Figure 6. An FIR filter in ADSP-2181 assembly language.

Note that this program uses DSP features that perform operations with zero overhead,
usually introduced by a conditional. In particular, program loops and data buffers are
maintained with zero overhead. The multifunction instruction in the core of the filter
loop performs a multiply/accumulate operation while the next data word and filter
coefficient are fetched from memory.
The program checks the final result of the filter calculation for any overflow. If the
final value has overflowed, the value is saturated to emulate the clipping of an analog
signal. Finally, the context of the main routine is restored and the instruction flow is
returned to the main routine with a return from interrupt (RTI) instruction.

Review and Preview


The goal of this article has been to provide a link between filter theory and digital
filter implementation. On the way, this article covers modeling filters with HLL
programs, using DSP architecture, and experimenting with filter software. The issues
introduced in this article include:

 Filters as programs
 DSP architecture (generalized)
 DSP assembly language

Because these issues involve many valuable levels of detail that one could not do
justice to in this brief article, you should consider reading Richard Higgins's
text, Digital Signal Processing in VLSI, and Paul Embree's text, C Algorithms For
Real Time DSP (see References below). These texts provides a complete overview of
DSP theory, implementation issues, and reduction to practice (with devices available
at the time of publication), plus exercises and examples. The Reference section below
also contains other sources that further amplify this article's issues. To prepare for the
next articles in this series, you might want to get free copies of the ADSP-2100
Family User's Manual* or the ADSP-2106x SHARC User's Manual.* These texts
provide information on Analog Devices's fixed- and floating-point DSP architectures,
a major topic in these articles. Working through this series, each part adds some
feature or information contributing to the series goal of developing a DSP system. To
reach this goal, the next article describes the series' development platform (the
ADSP-2181 EZ-KIT LITE) and introduces additional DSP development topics.

**

Por que usar um


DSP? [Digital Signal
Processing 101-Um curso
introdutório em DSP
System Design-Part 2]
de David Skolnick e Noam Levine baixar PDF

Se você leu a Parte 1 desta série (ou já está familiarizado com algumas das maneiras
pelas quais um DSP pode trabalhar com sinais do mundo real), talvez você queira
aprender mais sobre como os filtros digitais (como aqueles descritos na Parte 1) pode
ser implementado com um DSP. Este artigo, o segundo de uma série, apresenta os
seguintes tópicos do DSP:

 Funções de transformação de filtro de modelagem


 Relacionando os modelos com a arquitetura DSP
 Experimentando com filtros digitais
Esta série procura descrever esses tópicos da perspectiva de projetistas de sistemas
analógicos que desejam adicionar DSP ao seu repertório de design. Usando as
informações dos artigos desta série como uma introdução, os projetistas podem tomar
decisões mais informadas sobre quando os projetos de DSP podem ser mais
produtivos do que os circuitos analógicos.

Funções de transformação de filtro de


modelagem
A Parte 1 comparou as propriedades do filtro analógico e digital e sugeriu por que
alguém poderia implementar esses filtros digitalmente (usando DSP); Esta parte
concentra-se em algumas das mecânicas da aplicação do filtro digital.

As três principais razões para usar a filtragem digital são (1) abordagem mais próxima
das aproximações de filtro ideais, (2) capacidade de ajustar as características do filtro
em software e não por ajuste físico e (3) compatibilidade da resposta do filtro com
dados amostrados. Os dois filtros mais conhecidos descritos na Parte 1 são os tipos de
resposta ao impulso finito (FIR) e resposta ao impulso infinito (IIR). A resposta do
filtro FIR é chamada de finita porque sua saída é baseada unicamente em um conjunto
finito de amostras de entrada; é não-recursivo e não tem polos, apenas zeros em seu
s-plane. O filtro IIR, por outro lado, tem uma resposta que pode continuar
indefinidamente (e pode ser instável) porque é recursiva, ou seja, sua saída os valores
são afetados pela entrada e pela saída. Tem ambos os pólos e zeros no seu plano s. A
Figura 1 mostra as típicas arquiteturas de filtro e fórmulas de soma que apareceram na
Parte 1.

Figura 1. Equações de filtro e seus


modelos de linha de atraso.
Para modelar esses filtros digitalmente, pode-se dar dois passos. Primeiro, veja essas
fórmulas como programas em execução em um computador. Esta etapa consiste em
decompor a fórmula nas etapas matemáticas (por exemplo, multiplicar e adicionar) e
identificar todas as operações adicionais que seriam necessárias para um computador
executar (instruções e dados de manuseio, status de teste, etc.) para implementar a
fórmula. fórmula em software.

Segundo, pegue essas operações e escreva-as como um programa. Essa pode ser uma
tarefa bastante árdua. Felizmente, há muitos softwares "enlatados" disponíveis, muitas
vezes em uma linguagem de alto nível (HLL), como C, simplificando um pouco (mas
de forma alguma eliminando!) O trabalho de programação. Do ponto de vista da
aprendizagem, porém, pode ser mais instrutivo começar com a linguagem
assembly; também os algoritmos de linguagem assembly são geralmente mais úteis do
que o HLL, no qual o desempenho do sistema deve ser otimizado. No nível de
abstração de algumas linguagens de alto nível, o programa pode não se parecer muito
com as equações. Por exemplo, a Figura 2 mostra um exemplo de um algoritmo FIR
implementado como um programa em C. *

float fir_filter (entrada flutuante, float * coef, int n, float *


histórico)

int i;

float * hist_ptr, * hist1_ptr, * coef_ptr;

saída flutuante;

hist_ptr = history;

hist1_ptr = hist_ptr; / * use para atualização do histórico * /

coef_ptr = coef + n -1; / * aponta para o último coef * /

/ * formar acumulação de saída * /

saída = * hist_ptr ++ * (* coef_ptr-);

para (i = 2; i <n; i ++)

* hist1_ptr ++ = * hist_ptr; / * atualiza o array do histórico * /

saída + = (* hist_ptr ++) * (* coef_ptr-);

saída + = entrada * (* coef_ptr); / * toque de entrada * /

* hist1_ptr = entrada; / * última história * /


retorno (saída);

Figura 2. Filtro FIR como programa C

Existem muitos pacotes de análise disponíveis que suportam a modelagem de


algoritmos; veja as referências no final deste artigo para vários pacotes populares.
Voltaremos à modelagem de algoritmos em vários momentos ao longo desta
série. Agora, continuando a discussão do processo, depois que esses algoritmos de
filtro foram modelados, eles estão prontos para implementação na arquitetura DSP.

Relacionando os modelos à arquitetura DSP: Para programação, é preciso


entender quatro seções da arquitetura DSP: operações numéricas, de memória,
sequenciador e de E / S. Essa discussão de arquitetura é genérica (aplicada a conceitos
gerais de DSP), mas também é específica no que se refere a exemplos de programação
posteriormente neste artigo. A Figura 3 mostra a arquitetura DSP generalizada
descrita nesta seção.

Arquitetura
Seção Numérica: Como os DSPs devem concluir operações de multiplicação /
acumulação, adição, subtração e / ou deslocamento de bits em um único ciclo de
instrução, o hardware otimizado para operações numéricas é fundamental para todos
os processadores DSP. É esse hardware que distingue os DSPs dos
microprocessadores de uso geral, que podem exigir muitos ciclos para concluir esses
tipos de operações. Nos filtros digitais (e outros algoritmos DSP), o DSP deve
completar várias etapas de operações aritméticas envolvendo valores de dados e
coeficientes, para produzir respostas em tempo real que não foram possíveis com
processadores de uso geral.

As operações numéricas ocorrem dentro de um multiplexador / acumulador (MAC),


unidade lógica aritmética (ALU), e deslocador de barril (shifter). O MAC executa
operações de soma de produtos, que aparecem na maioria dos algoritmos DSP (como
filtros FIR e IIR e transformadas rápidas de Fourier). Os recursos da ALU incluem
operações de adição, subtração e lógica. Operações em bits e palavras ocorrem dentro
do shifter. A Figura 3 mostra o paralelismo do MAC, ALU e shifter e como os dados
podem entrar e sair deles.
Figura 3. Uma arquitetura útil de DSP.

Do ponto de vista da programação, uma arquitetura DSP que usa seções numéricas
separadas fornece grande flexibilidade e eficiência. Existem muitos caminhos não
conflitantes para dados, permitindo a conclusão de ciclo único de operações
numéricas. A arquitetura do DSP também deve fornecer um amplo intervalo dinâmico
para operações MAC, com a capacidade de lidar com resultados de multiplicação que
são o dobro da largura das saídas de entradas e acumulações que podem ser montadas
sem transbordamento. (Em um DSP de 16 bits, esse recurso equivale a entradas de
dados de 16 bits e uma saída de resultados de 40 bits do MAC.) É necessário esse
intervalo para manipular a maioria dos algoritmos de DSP (como filtros).

Outras características da seção numérica podem facilitar a programação em sistemas


em tempo real. Ao tornar as operações dependentes de uma variedade de estados
condicionais, que resultam de operações numéricas, elas podem servir como variáveis
na execução de um programa, testando carry, overflows, saturates, flags ou
outros estados. Usando essas condicionais, um DSP pode manipular rapidamente as
decisões sobre o fluxo do programa com base em operações numéricas. A necessidade
de estar constantemente alimentando dados na seção numérica é uma influência chave
do design na memória do DSP e nas estruturas de barramento interno.

Seção de memória: O design de arquitetura de barramento e memória DSP é guiado


pela necessidade de velocidade. Os dados e instruções devem fluir para as seções
numéricas e de seqüenciamento do DSP em cada ciclo de instrução. Não pode haver
atrasos nem gargalos. Tudo sobre o design se concentra no rendimento.

Etimologia de Harvard e von Neumann Architectures - De acordo com John AN Lee,


Departamento de Ciência da Computação, Virginia Tech:

"Howard Aiken, desenvolvedor da série de máquinas Harvard, insistiu na separação


de dados e programas em todas as suas máquinas. No Mark III, que eu conheço
melhor, ele até tinha tambores de tamanhos diferentes para cada um."

"O conceito de von Neumann era que, ao tratar as instruções como dados, era possível
fazer alterações nos programas, aumentando a capacidade de os programas"
aprenderem "."

"Por alguma razão, este último recebeu o nome de von Neumann, enquanto o
primeiro recebeu o nome da linha de máquinas de Harvard."
Para colocar esse foco na taxa de transferência em perspectiva, pode-se observar a
diferença entre o design da memória DSP e a memória para outros
microprocessadores. A maioria dos microprocessadores usa um único espaço de
memória contendo dados e instruções, usando um barramento para endereço e outro
para dados ou instruções. Essa arquitetura é chamada de arquitetura de von
Neumann. A limitação na taxa de transferência em uma arquitetura von Neumann
vem de ter que escolher entre um dado ou uma instrução em cada ciclo. Nos DSPs, a
memória é tipicamente dividida em programa e memória de dados - com barramentos
separados para cada um. Esse tipo de arquitetura é conhecido como arquitetura de
Harvard. Ao separar os dados e as instruções, o DSP pode buscar vários itens em cada
ciclo, duplicando o rendimento. Otimizações adicionais, como cache de instruções,
feedback de resultados e comutação de contexto também aumentam o throughput do
DSP.

Outras otimizações na arquitetura de memória DSP referem-se a acessos repetidos à


memória. A maioria dos algoritmos DSP, como filtros digitais, precisa obter dados da
memória em um padrão repetitivo de acessos. Normalmente, esse tipo de acesso serve
para buscar dados de um intervalo de endereços, um intervalo preenchido com dados
dos sinais reais a serem processados. Ao reduzir o número de instruções necessárias
para "gerenciar" os acessos à memória (overhead), os DSPs "economizam" ciclos de
instruções, permitindo mais tempo para o trabalho principal de cada ciclo de
processamento de sinais. Para reduzir a sobrecarga e gerenciar automaticamente esses
tipos de acessos, os DSPs utilizam geradores de endereços de dados especializados
(DAGs).

A maioria dos algoritmos DSP exige que dois operandos sejam buscados da memória
em um único ciclo para se tornarem entradas para as unidades aritméticas. Para
fornecer os endereços desses dois operandos de maneira flexível, o DSP possui dois
DAGs. Na arquitetura modificada de Harvard do DSP, um gerador de endereço
fornece um endereço através do barramento de endereço de memória de dados; o
outro fornece um endereço através do barramento de endereços da memória do
programa. Ao realizar essas duas buscas de dados a tempo para a próxima instrução
numérica, o DSP é capaz de sustentar a execução de instruções de ciclo único.

Algoritmos de DSP, como os filtros digitais de exemplo, geralmente requerem que os


dados em um intervalo de endereços (um buffer) sejam endereçados para que o
ponteiro de endereço "contorne" do fim do buffer de volta ao início do
buffer comprimento ). Este movimento do ponteiro é chamado tamponamento
circular . (Nas equações de filtro, cada soma resulta basicamente de uma sequência de
multiplicação e acumulação de um buffer circular de pontos de dados e um buffer
circular de coeficientes). Uma variação do buffer circular, que é necessária em alguns
aplicativos, avança o ponteiro de endereço por valores maiores que um endereço por
"etapa", mas ainda envolve um determinado comprimento. Essa variação é
chamada modulo buffer circular .

Ao suportar vários tipos de buffering com seus DAGs, o DSP pode executar a
modificação de endereço e comparar as operações no hardware para obter a eficiência
ideal. A execução dessas funções no software (como ocorre em processadores de uso
geral) limita a capacidade do processador de manipular sinais em tempo real.
Como o armazenamento em buffer é um conceito incomum, mas essencial para o
processamento digital de sinais, um breve exemplo de armazenamento em buffer é
útil. No exemplo ilustrado na Figura 4, um buffer de oito locais reside na memória
que começa no endereço 30. O gerador de endereços deve calcular os próximos
endereços que permanecem dentro desse buffer e manter o espaçamento de dados
adequado para que dois locais sejam ignorados. O gerador de endereços envia o
endereço 30 para o barramento de endereços enquanto modifica o endereço para 33
para o acesso à memória do próximo ciclo.Esse processo se repete, movendo o
ponteiro de endereço pelo buffer. Um caso especial ocorre quando o endereço 36 é
modificado para 39. O endereço 39 está fora do buffer. O gerador de endereços
detecta que o endereço caiu fora do limite do buffer e modifica o endereço para 31,
como se o final do buffer estivesse conectado ao início do buffer. o atualizar,
comparar e modificar ocorrer sem sobrecarga . Em um ciclo, o endereço 36 é
enviado para o barramento de endereços. No próximo ciclo, o endereço 31 é enviado
para o barramento de endereços. Esse módulo de buffer circular atende às
necessidades de algoritmos como filtros de interpolação e salva ciclos de instrução
para processamento.

Figura 4. Exemplo de
buffer circular do módulo.

Seção do seqüenciador: Como a maioria dos algoritmos de DSP (como os filtros de


exemplo) são, por natureza, repetitivos, o sequenciador de programas do DSP precisa
percorrer o código repetido sem incorrer em sobrecarga ao passar do final do loop de
volta ao início do loop. Esse recurso é chamado de loop de sobrecarga zero. Ter a
capacidade de fazer o loop sem sobrecarga é uma área chave na qual os DSPs diferem
dos microprocessadores convencionais. Normalmente, os microprocessadores exigem
que os loops de programa sejam mantidos no software, colocando uma instrução
condicional no final do loop. Essa instrução condicional determina se o ponteiro de
endereço se move (salta) de volta para o início do loop ou para outro endereço. Como
obter esses endereços da memória leva tempo e a disponibilidade de tempo para o
processamento de sinal é crítica em aplicativos de DSP, os DSPs não podem
desperdiçar ciclos recuperando endereços para o sequenciamento de programa
condicional (ramificação) dessa maneira. Em vez disso, os DSPs executam essas
funções de teste e ramificação no hardware, armazenando os endereços necessários.

Como mostra a Figura 5, o DSP executa a última instrução do loop em um ciclo. No


próximo ciclo, o DSP avalia o condicional e executa a primeira instrução na parte
superior do loop ou a primeira instrução fora do loop. Como o DSP usa hardware
dedicado para essas operações, nenhum tempo extra é desperdiçado com o software
avaliando condicionais, recuperando endereços ou execução de programas de
ramificação.

Figura 5.
Exemplo de loop de programa.

Seção de entrada / saída (E / S): Conforme observado repetidas vezes, há uma


necessidade de uma tremenda taxa de transferência de dados para o DSP; tudo sobre o
seu design é focado em canalizar dados para dentro e fora das seções numéricas, de
memória e sequenciador. A fonte dos dados e o destino da saída (o resultado do
processamento do sinal) é a conexão do DSP com seu sistema e com o mundo
real.Diversas funções de E / S são necessárias para concluir as tarefas de
processamento de sinal. Matrizes de memória fora do DSP armazenam instruções e
dados do processador. Canais de comunicação (como portas seriais, portas de E / S e
canais de acesso direto à memória (DMA) transferem dados para dentro e fora do
DSP rapidamente. Outras funções (como temporizadores e lógica de inicialização do
programa) facilitam o desenvolvimento do sistema DSP. As tarefas típicas de E / S
em um sistema DSP incluem o seguinte (entre muitas outras):

 Carregamento de inicialização : Na reinicialização, o DSP carrega instruções


de uma fonte externa (EPROM ou host) geralmente por meio de uma interface
de memória externa.
 Comunicações seriais : O DSP recebe ou transmite dados por meio de uma
porta serial síncrona (SPORT), comunicando-se com codecs, ADCs, DACs ou
outros dispositivos.
 E / S mapeada na memória: O DSP recebe ou transmite dados através de
um local de memória fora do DSP que é descodificado por um dispositivo
externo.

Experimentando com Filtros Digitais


Tendo modelado os algoritmos de filtro e analisado alguns dos recursos arquiteturais
do DSP, está pronto para começar a verificar como esses filtros podem ser codificados
na linguagem assembly do DSP.Até este ponto, a discussão e os exemplos foram
genéricos, aplicando-se a quase todos os DSPs. Aqui, o exemplo é específico para o
Analog Devices ADSP-2181. Este processador é um DSP de 16 bits de ponto fixo. O
termo "ponto fixo" significa que o "ponto" que separa a mantissa e o expoente não
altera sua localização de bit durante operações aritméticas. Os DSPs de ponto fixo
podem ser mais difíceis de programar, mas tendem a ser menos caros do que os DSPs
de ponto flutuante. O "16 bits" em "DSP de 16 bits" refere-se ao tamanho das palavras
de dados do DSP. Este DSP utiliza palavras de dados de 16 bits e palavras de
instrução de 24 bits. Os DSPs são especificados pelo tamanho dos dados, em vez da
largura da instrução, porque o tamanho da palavra de dados descreve a largura dos
dados que o DSP pode manipular com mais eficiência.

O programa de exemplo na Figura 6 é um filtro FIR na linguagem assembly


ADSP-2181. O software tem duas partes. A rotina principal inclui a inicialização do
registrador e do buffer junto com a tabela de vetores de interrupção e a rotina de
interrupção que é executada quando uma amostra de dados está pronta. Após a
inicialização, o DSP executa instruções na rotina principal, executando algumas
tarefas em segundo plano, fazendo o loop através do código ou inativo em um modo
de espera de baixa energia até que ele receba uma interrupção do conversor A /
D. Neste exemplo, o processador fica ocioso em um modo de espera de baixa energia
aguardando uma interrupção.

A sub-rotina de interrupção do filtro FIR (o último segmento de código) é o coração


do programa de filtragem. O processador responde à interrupção, salvando o contexto
da rotina principal e pulando para a rotina de interrupção. Essa rotina de interrupção
processa a amostra de entrada do filtro, lendo dados e filtrando coeficientes da
memória e armazenando-os em registros de dados do processador DSP. Depois de
processar a amostra de entrada, o DSP envia uma amostra de saída para o conversor D
/ A.

.module / RAM / ABS = 0 FIR_PROGRAM;

/ ******** Inicializar constantes e variáveis ***************** /

.constantes = 127;

dados .var / dm / circ [toques];

.var / pm / circ fir_coefs [toques];

.init fir_coefs:;

.var / dm / circ output_data [toques];

/ ******** Tabela de vetores de interrupção


***************************** /

reset_svc: jump start; rti; rti; rti;

/ * 00: reset * /

irq2_svc: / * 04: IRQ2 * /

si = io (0); / * obter a próxima amostra * /

dm (i0, m0) = si; / * armazenar na linha de atraso de toque * /


pular abeto; / * pula para o filtro de vaga * /

nop; / * nop é espaço reservado * /

irql1_svc: rti; rti; rti; rti; / * 08: IRQL1 * /

irql0_svc: rti; rti; rti; rti; / * 0c: IRQL0 * /

sp0tx_svc: rti; rti; rti; rti; / * 10: SPORT0 tx * /

sp0rx_svc: rti; rti; rti; rti; / * 14: SPORT1 rx * /

irqe_svc: rti; rti; rti; rti; / * 18: IRQE * /

bdma_svc: rti; rti; rti; rti; / * 1c: BDMA * /

sp1tx_svc: rti; rti; rti; rti; / * 20: SPORT1 tx ou IRQ1 * /

sp1rx_svc: rti; rti; rti; rti; / * 24: SPORT1 rx ou IRQ0 * /

timer_svc: rti; rti; rti; rti; / * 28: temporizador * /

pwdn_svc: rti; rti; rti; rti; / * 2c: desligar * /

/ ******* START OF PROGRAM - inicializar máscara, ponteiros **********


/

começar:

/ * configurar vários registros de controle * /

ICNTL = 0x07; / * definir IRQ2, IRQ1, IRQ0 sensível à borda * /

IFC = 0xFF; / * limpar todas as interrupções pendentes * /

NOP; / * add nop por causa de um ciclo * /

/ * atraso de sincronização do IFC * /

SI = 0x0000;

DM (0x3FFF) = SI; / * esportes não habilitados * /

/ * sport1 definido para IRQ1, IRQ0, FI, FO * /

IMASK = 0x200; / * habilitar a interrupção de IRQ2 * /

i0 = ^ dados; / * indexar ao buffer de dados * /

l0 = taps; / * comprimento do buffer de dados * /

m0 = 1; / * pós modificar valor * /

i4 = ^ fir_coefs; / * index para o buffer fir_coefs * /


l4 = torneiras; / * comprimento do buffer fir_coefs * /

m4 = 1; / * pós modificar valor * /

i2 = ^ output_data; / * indexar ao buffer de dados * /

l2 = torneiras; / * comprimento do buffer de dados * /

cntr = taps;

faça zero até ce;

dm (i0, m0) = 0; / * limpar o buffer de dados de atraso de tap * /

zero: dm (i2, m0) = 0; / * limpar o buffer output_data * /

/ **** ESPERE por IRQ2 Interromper - então JUMP para INTERRUPÇÃO VETOR
** /

espera: ocioso; / * aguarde a interrupção do IRQ2 * /

pule a espera;

/ ******* FIR FILTER interrompe a sub-rotina *********************** /

fir cntr = taps-1; / * configurar contador de loops * /

mr = 0, mx0 = dm (i0, m0), my0 = pm (i4, m4);

/ * buscar dados e coeficiente * /

do fir1loop até ce; / * configurar loop * /

fir1loop: mr = mr + mx0 * my0 (ss), mx0 = dm (i0, m0), my0 = pm (i4, m4);

/ * cálculos * /

/ * if not ce jump fir1loop; * /

mr = mr + mx0 * my0 (rnd); / * resultado final arredondado para 16 bits


* /

se mv sentou mr; / * se transbordar, saturar * /

io (1) = mr1; / * enviar resultado para o DAC * /

dm (i2, m0) = mr1;

rti;

/ ******* FIM DO PROGRAMA ************************************* /

.endmod;
Figura 6. Um filtro FIR na linguagem assembly ADSP-2181.

Observe que este programa usa recursos de DSP que executam operações com
sobrecarga zero, geralmente introduzidas por uma condicional. Em particular, loops
de programa e buffers de dados são mantidos com sobrecarga zero. A instrução
multifuncional no núcleo do loop de filtro executa uma operação de multiplicação /
acumulação enquanto a próxima palavra de dados e o coeficiente do filtro são
buscados da memória.

O programa verifica o resultado final do cálculo do filtro para qualquer estouro. Se o


valor final tiver transbordado, o valor é saturado para emular o recorte de um sinal
analógico. Finalmente, o contexto da rotina principal é restaurado e o fluxo de
instrução é retornado para a rotina principal com uma instrução de retorno da
interrupção (RTI).

Revise e visualize
O objetivo deste artigo foi fornecer uma ligação entre a teoria dos filtros e a
implementação do filtro digital. No caminho, este artigo aborda a modelagem de
filtros com programas HLL, usando arquitetura DSP e experimentando softwares de
filtro. Os problemas introduzidos neste artigo incluem:

 Filtros como programas


 Arquitetura DSP (generalizada)
 Linguagem assembly DSP
Como essas questões envolvem muitos níveis valiosos de detalhes que não se pode
fazer justiça neste breve artigo, você deve considerar a leitura do texto de Richard
Higgins, Processamento Digital de Sinais no VLSI , e o texto de Paul
Embree, Algoritmos C para DSP em Tempo Real (ver referências abaixo). Estes
textos fornecem uma visão completa da teoria DSP, questões de implementação e
redução à prática (com dispositivos disponíveis no momento da publicação), além de
exercícios e exemplos. A seção de referência abaixo também contém outras fontes
que amplificam ainda mais os problemas deste artigo. Para se preparar para os
próximos artigos desta série, talvez você queira obter cópias gratuitas do Manual do
Usuário da Família ADSP-2100 * ou do Manual do Usuário SHARP da ADSP-2106x.
* Esses textos fornecem informações sobre DSP de ponto fixo e flutuante da Analog
Devices. arquiteturas, um tema importante nesses artigos. Ao trabalhar com essa série,
cada parte adiciona algum recurso ou informação que contribui para o objetivo da
série de desenvolver um sistema DSP. Para alcançar esse objetivo, o próximo artigo
descreve a plataforma de desenvolvimento da série (o ADSP-2181 EZ-KIT LITE) e
apresenta tópicos adicionais de desenvolvimento de DSP.
DSP 101 Part 3:
Implement Algorithms
on a Hardware Platform
by Noam Levine and David Skolnick Download PDF

So far, we have described the physical architecture of the DSP processor, explained
how DSP can provide some advantages over traditionally analog circuitry, and
examined digital filtering, showing how the programmable nature of DSP lends itself
to such algorithms. Now we look at the process of implementing a finite-impulse-
response (FIR) filter algorithm (briefly introduced in Part 2, implemented in
ADSP-2100 Family assembly code) on a hardware platform, the ADSP-2181 EZ-Kit
Lite&tm;. The implementation is expanded to handle data I/O issues.

Using Digital Filters


Many of the architectural features of the DSP, such as the ability to perform
zero-overhead loops, and to fetch two data values in a single processor cycle, will be
useful in implementing this filter. Reviewing briefly, an FIR filter is an all-zeros filter
that is calculated by convolving an input data-point series with filter coefficients. Its
governing equation and direct-form representation are shown in Figure 1.

Figure 1. Direct-form FIR filter structure.


In this structure, each "z–1 " box represents a single increment of history of the input
data in z-transform notation. Each of the successively delayed samples is multiplied
by the appropriate coefficient value, h(m), and the results, added together, generate a
single value representing the output corresponding to the nth input sample. The
number of delay elements, or filter taps, and their coefficient values, determine the
filter’s performance.

The filter structure suggests the physical elements needed to implement this algorithm
by computation using a DSP. For the computation itself, each output sample requires
a number of multiply-accumulate operations equal to the length of the filter.
The delay line for input data and the coefficient value list require reserved areas of
memory in the DSP for storing data values and coefficients. The DSP’s enhanced
Harvard architecture lets programmers store data in Program Memory as well as in
Data Memory, and thus perform two simultaneous memory accesses in every cycle
from the DSP’s internal SRAM. With Data Memory holding the incoming samples,
and Program Memory storing the coefficient values, both a data value and a
coefficient value can be fetched in a single cycle for computation.

This DSP architecture favors programs that use circular buffering (discussed briefly in
Part 2 and later in this installment). The implication is that address pointers need to be
initialized only at the beginning of the program, and the circular buffering mechanism
ensures that the pointer does not leave the bounds of its assigned memory buffer—a
capability used extensively in the FIR filter code for both input delay line and
coefficients. Once the elements of the program have been determined, the next step is
to develop the DSP source code to implement the algorithm.

Developing DSP Software


Software development flow for the ADSP-2100 Family consists of the following steps:
architecture description, source-code generation, software validation (debugging), and
hardware implementation. Figure 2 shows a typical development cycle.

Figure 2. Software development flow.


Architecture description: First, the user creates a software description of the
hardware system on which the algorithm runs. The system description file includes all
available memory in the system and any memory-mapped external peripherals. Below
is an example of this process using the ADSP-2181 EZ-Kit Lite.

Source-code generation: Moving from theory into practice, this step—where an


algorithmic idea is turned into code that runs on the DSP—is often the most
time-consuming step in the process. There are several ways to generate source code.
Some programmers prefer to code their algorithms in a high-level language such as C;
others prefer to use the processor’s native assembly language. Implementations in C
may be faster for the programmer to develop, but compiled DSP code lacks efficiency
by not taking full advantage of a processor’s architecture.

Assembly code, by taking full advantage of a processor’s design, yields highly


efficient implementations. But the programmer needs to become familiar with the
processor’s native assembly language. Most effective is combining C for high-level
program-control functions and assembly code for the time-critical, math-intensive
portions of the system. In any case, the programmer must be aware of the processor’s
system constraints and peripheral specifics. The FIR filter system example in this
article uses the native assembly language of the ADSP-2100 Family.

Software validation ("debugging"): This phase tests the results of code


generation—using a software tool known as a simulator— to check the logical flow
of the program and verify that an algorithm is performing as intended. The simulator
is a model of the DSP processor that a) provides visibility into all memory locations
and processor registers, b) allows the user to run the DSP code either continuously or
one instruction at a time, and c) can simulate external devices feeding data to the
processor.

Hardware implementation: Here the code is run on a real DSP, typically in several
phases: a) tryout on an evaluation platform such as EZ-Kit Lite; b) in-circuit
emulation, and c) production ROM generation. Tryout provides a quick go/no-go
determination of the program’s operation; this technique is the implementation
method used in this article. In-circuit emulation monitors software debug in the
system, where a tool such as an EZ-ICE™ controls processor operation on the target
platform. After all debug is complete, a boot ROM of the final code can be generated;
it serves as the final production implementation.

Working With the ADSP-2181 EZ-Kit Lite


Our example of the development cycle walks through the process, using the
ADSP-2181 EZ-Kit Lite (development package ADDS-21xx- EZLITE) as the target
hardware for the filter algorithm. The EZ-Kit Lite, a low-cost demonstration and
development platform, consists of a 33-MHz ADSP-2181 processor, an AD1847
stereo audio codec, and a socketed EPROM, which contains monitor code for
downloading new algorithms to the DSP through an RS-232 connection (Figure 3).
Figure
3. Layout of EZ-Kit Lite board.
To complete the architecture description phase, one needs to know the memory and
memory-mapped peripherals that the DSP has available to it. Programmers store this
information in a system-description file so that the development tools software can
produce appropriate code for the target system. The EZ-Kit Lite needs no memory
external to the DSP, because available memory on-chip consists of the 16,384
locations of the ADSP-2181’s Program Memory (PM) SRAM, and 16,352 locations
of Data Memory (DM) SRAM. (32 DM locations used for system control registers are
not available for working code). More information on the ADSP-2181, the EZ-Kit
Lite’s architecture, and related topics, can be found in texts mentioned at the end of
this article.

Available system resources information is recorded in a system description file for use
by the ADSP-2100 Family development tools. A system description file has a .SYS
extension. The following list shows a system description file [EZKIT_LT.SYS]:

.system EZ_LITE; /* gives a name to this system */

.adsp2181; /* specifies the processor */

.mmap0; /* specifies that the system boots and that */,

/* PM location 0 is in internal memory */

.seg/PM/RAM/ABS=0/code/data int_pm[16384];

.seg/DM/RAM/ABS=0 int_dm[16352];

.endsys; /* ends the description */

The listing declares 16,384 locations of PM as RAM, starting at address 0, to let both
code segments and data values be placed there. Also declared are 16,352 available
locations of data memory as RAM, starting at address 0. Because these processors use
a Harvard architecture with two distinct memory spaces, PM address 0 is distinct from
DM address 0. The ADSP-2181 EZ-Kit Lite’s codec is connected to the DSP using a
serial port, which is not declared in the system description file. To make the system
description file available to other software tools, the System Builder utility, BLD21,
converts the .SYS file into an architecture, or .ACH, file. The output of the System
Builder is a file named EZKIT_LT.ACH.

After writing the code, the next step is to generate an executable file, i.e., turn the
code into instructions that the DSP can execute. First one assembles the DSP code.
This converts the program file into a format that the other development tools can
process. Assembling also checks the code for syntax errors. Next, one links the code
to generate the DSP executable, using the available memory that is declared in the
architecture file. The Linker fits all of the code and data from the source code into the
memory space; the output is a DSP executable file, which can be downloaded to the
EZ-Kit Lite board.

Generating Filter Code


Part 2 of this series [Analog Dialogue 31-2, page 14, Figure 6] introduced a small
assembly code listing for an FIR filter. Here, that code is augmented to incorporate
some EZ-Kit Lite-specific features, specifically codec initialization and data I/O. The
core filter-algorithm elements (multiply-accumulates, data addressing using circular
buffers for both data and coefficients, and reliance on the efficiency of the
zero-overhead loop) do not change.

The incoming data will be sampled using the on-board AD1847 codec, which has
programmable sampling rate, input gain, output attenuation, input selection, and input
mixing. Its programmable nature makes the system flexible, but it also adds a task of
programming to initialize it for the DSP system.

Accessing Data
For this example, a series of control words to the codec—to be defined at the
beginning of the program in the first section of the listing—will initialize it for an
8-kHz sampling rate, with moderate gain values on each of the input channels. Since
the AD1847 is programmable, users would typically reuse interface and initialization
code segments, changing only the specific register values for different applications.
This example will add the specific filter segment to an existing code segment found in
the EZ-Kit Lite software.

This interface code declares two areas in memory to be used for data I/O: "tx_buf",
for data to be transmitted out of the codec, and "rx_buf", where incoming data is
received. Each of these memory areas, or buffers, contains three elements, a control or
status word, left-channel data, and right-channel data. For each sample period, the
DSP will receive from the codec a status word, left channel data, and right channel
data. On every sample period, the DSP must supply to the codec a transmit control
word, left channel data, and right channel data. In this application, the control
information sent to the codec will not be altered, so the first word in the transmit data
buffer will be left as is. We will assume that the source is a monophonic microphone,
using the right channel (no concern about left-channel input data).

Using the I/O shell program found in the EZ-Kit Lite software, we need only be
involved with the section of code labeled "input_samples". This section of code is
accessed when new data is received from the codec ready to be processed. If only the
right channel data is required, we need to read the data located in data memory at
location rx_buf + 2, and place it in a data register to be fed into the filter program.

The data arriving from the codec needs to be fed into the filter algorithm via the input
delay line, using the circular buffering capability of the ADSP-2181. The length of the
input delay line is determined by the number of coefficients used for the filter.
Because the data buffer is circular, the oldest data value in the buffer will be wherever
the pointer is pointing after the last filter access (Figure 4) . Likewise the coefficients,
always accessed in the same order every time through the filter, are placed in a
circular buffer in Program Memory.

Figure 4. Example of using circular buffers for filter data input.

Algorithm Code
To operate on the received data, the code section published in the last installment can
be used with few modifications. To implement this filter, we need to use the
multiply/accumulate (MAC) computational unit and the data address-generators.

The ADSP-2181’s MAC stores the result in a 40-bit register (32 bits for the product
of 2 16-bit words, and 8 bits to allow the sum to expand without overflowing). This
allows intermediate filter values to grow and shrink as necessary without corrupting
data. The code segment being used is generic (i.e., can be used for any length filters);
so the MAC’s extra output bits allow arbitrary filters with unknown data to be run
with little fear of losing data.

To implement the FIR filter, the multiply/accumulate operation is repeated for all taps
of the filter on each data point. To do this (and be ready for the next data point), the
MAC instruction is written in the form of a loop. The ADSP-21xx’s zero-overhead
loop capability allows the MAC instruction to be repeated for a specified number of
counts without programming intervention. A counter is set to the number of taps
minus one, and the loop mechanism automatically decrements the counter for each
loop operation. Setting the loop counter to "taps–1" ensures that the data pointers end
up in the correct location after execution is finished and allows the final MAC
operation to include rounding. As the AD1847 is a 16-bit codec, the MAC with
rounding provides a statistically unbiased result rounded to the nearest 16-bit value.
This final result is written to the codec.

For optimal code execution, every instruction cycle should perform a meaningful
mathematical calculation. The ADSP-21xxs accomplish this with multi-function
instructions: the processor can perform several functions in the same instruction cycle.
For the FIR filter code, each multiply-accumulate (MAC) operation can be performed
in parallel with two data accesses, one from Data Memory, one from Program
Memory. This capability means that on every loop iteration a MAC operation is being
performed. At the same time, the next data value and coefficient are being fetched,
and the counter is automatically decremented. All without wasting time maintaining
loops.

As the filter code is executed for each input data sample, the output of the MAC loop
will be written to the output data buffer, tx_buf. Although this program only deals
with single-channel input data, the result will be written out to both channels by
writing to memory buffer addresses tx_buf+1 and tx_buf+2.

The final source code listing is shown on page 15. The filter algorithm itself is listed
under "Interrupt service routines". The rest of the code is used for codec and DSP
initialization and interrupt service routine definition. Those topics will be explored in
future installments of this series.

The EZ-Kit Lite


The Windows-based monitor software provided with the EZ-Kit Lite, makes it
possible to load an executable file into the ADSP-2181 on the EZ-Kit Lite board. This
is accomplished through the pull-down "Loading" menu by selecting "Download user
program and Go" (Figure 5). This will download the filter program to the ADSP-2181
and start program execution.
Figure 5. EZ-Kit Lite download menu.

Review and Preview


The goal of this article was to outline the steps from an algorithm description to a
DSP executable program that could be run on a hardware development platform.
Issues introduced include software development flow, architecture description,
source-code generation, data I/O, and the EZ-Kit Lite hardware platform.

There are many levels of detail associated with each of these topics that this brief
article could not do justice to. Further information is available in the references below.
The series will continue to build on this application with additional topics. The next
article will examine data input/output (I/O) issues in greater detail through the
processor interrupt structure, and discuss additional features of the simple filter
algorithm.

FIR Filter code listing for EZ-Kit Lite


/*****************************************************
*********

* hello81.dsp — template file for 2181 ez-kit lite board


*

* This sample program is organized into the following sections:

* Assemble time constants (system.h)

* Interrupt vector table

* ADSP 2181 intialization (init1847.dsp)

* ADSP 1847 codec intialization (init1847.dsp)

* Interrupt service routines

* This program implements a simple ‘talk-through’ with the AD1847


codec.

* The initialization routines have been put into the init1847.dsp file.
This

* file contains the interrupt vector table, the main ‘dummy’ loop, and
the

* interrupt service routines for the pushbutton and the serial port 0
receive.

* The pushbutton (IRQE) causes the LED on the EZ-Kit board to toggle

* with each button press.

* Parameters controlling the sampling rate, gains, etc., are contained


in the

* file init1847.dsp. Serial Port 0 is used to communicate with the


AD1847.

* The transmit interrupts are used to configure the codec, then they
are

* disabled and the receive interrupts are used to implement the


‘talk-through’

* audio.

* The definitions for the memory-mapped control registers are


contained in

* the file: system.h

* The application can be built by:

* asm21 -c -l -2181 hello81

* asm21 -c -l -2181 init1847

* ld21 hello81 init1847 -a 2181 -e hello81 -g -x

******************************************************
****/

.module/RAM/ABS=0 EzHello;

#include

#define taps 255 /* filter tap length */

.var/dm/circ filt_data[taps]; /* input data buffer */

.var/pm/circ filt_coeffs[taps]; /* coefficient buffer */

.init filt_coeffs:; /* initialize coefficients */

.external rx_buf, tx_buf;

.external init_cmds, stat_flag;

.external next_cmd, init_1847, init_system_regs, init_sport0;

/*****************************************************
*****

* Interrupt vector table

******************************************************
****/

jump start; rti; rti; rti; /* 00: reset */

rti; rti; rti; rti; /* 04: IRQ2 */

rti; rti; rti; rti; /* 08: IRQL1 */

rti; rti; rti; rti; /* 0c: IRQL0 */

ar = dm(stat_flag); /* 10: SPORT0 tx */

ar = pass ar;

if eq rti;

jump next_cmd;

jump input_samples; /* 14: SPORT1 rx */

rti; rti; rti;

jump irqe; rti; rti; rti; /* 18: IRQE */

rti; rti; rti; rti; /* 1c: BDMA */

rti; rti; rti; rti; /* 20: SPORT1 tx or IRQ1 */

rti; rti; rti; rti; /* 24: SPORT1 rx or IRQ0 */

rti; rti; rti; rti; /* 28: timer */

rti; rti; rti; rti; /* 2c: power down */

/*****************************************************
*******

* ADSP 2181 intialization

******************************************************
******/
start:

i0 = ^rx_buf; /* remember codec autobuffering uses i0 and i1 !! */

l0 = %rx_buf;

i1 = ^tx_buf;

l1 = %tx_buf;

i3 = ^init_cmds; /* i3 can be used for something else after codec init


*/

l3 = %init_cmds;

m0 = 0;

m1 = 1;

/* initialize serial port 0 for communication with the AD1847 codec */

call init_sport0;

/* initialize the other system registers, etc. */

call init_system_regs;

/* initialize the AD1847 codec */

call init_1847;

ifc = b#00000011111111; /* clear any pending interrupt */

nop; /* there is a 1 cycle latency for ifc */

/* setup pointers for data and coefficients */

i2 = ^filt_data;

l2 = %filt_data;

i5 = ^filt_coefs;

m5 = 1;

l5 = %filt_coefs;
imask=b#0000110000; /* enable rx0 interrupt */

/* |||||||||+ | timer

||||||||+- | SPORT1 rec or IRQ0

|||||||+-- | SPORT1 trx or IRQ1

||||||+--- | BDMA

|||||+---- | IRQE

||||+----- | SPORT0 rec

|||+------| SPORT0 trx

||+-------| IRQL0

|+--------| IRQL1

+---------| IRQ2

*/

/*----------------------------------------------------------------------

- wait for interrupt and loop forever

----------------------------------------------------------------------*/

talkthru: idle;

jump talkthru;

/*****************************************************
*********

* Interrupt service routines

******************************************************
********/

/*----------------------------------------------------------------------

- FIR Filter

----------------------------------------------------------------------*/
input_samples:

ena sec_reg; /* use shadow register bank */

ax0 = dm (rx_buf + 1); /* read data from converter */

dm(i2,m1) = ax0; /* write new data into delay line, pointer

now pointing to oldest data */

cntr = taps - 1;

mr = 0, mx0 = dm(i2,m1), my0 = pm(i5,m5); /* clear accumulator,


get first

data and coefficient value */

do filt_loop until ce; /* set-up zero-overhead loop */

filt_loop: mr = mr + mx0 * my0(ss), mx0 = dm(i2,m1), my0 =


pm(i5,m5);

/* MAC and two data fetches */

mr = mr + mx0 * my0 (rnd); /* final multiply, round to 16-bit result


*/

if mv saat mr; /* check for overflow */

dm(tx_buf+1) = mr1;

dm(tx_buf+2) = mr1; /* output data to both channels */

rti;

.endmod;

**
DSP 101 Parte 3:
Algoritmos de
Implementos em uma
Plataforma de Hardware
de Noam Levine e David Skolnick baixar PDF

Até agora, descrevemos a arquitetura física do processador DSP, explicamos como o


DSP pode oferecer algumas vantagens em relação aos circuitos analógicos
tradicionais e examinamos a filtragem digital, mostrando como a natureza
programável do DSP se presta a esses algoritmos. Agora analisamos o processo de
implementação de um algoritmo de filtro de resposta ao impulso finito (FIR)
(brevemente apresentado na Parte 2, implementado no código assembly ADSP-2100
Family) em uma plataforma de hardware, o ADSP-2181 EZ-Kit Lite & tm. A
implementação é expandida para lidar com problemas de E / S de dados.

Usando filtros digitais


Muitos dos recursos de arquitetura do DSP, como a capacidade de executar loops de
sobrecarga zero e de buscar dois valores de dados em um único ciclo de processador,
serão úteis na implementação desse filtro. Revendo brevemente, um filtro FIR é um
filtro de zeros que é calculado através da convolução de uma série de pontos de dados
de entrada com coeficientes de filtro. Sua equação governante e representação de
forma direta são mostradas na Figura 1.

Figura 1. Estrutura do filtro FIR de formato direto.

Nesta estrutura, cada "z –1 "box representa um único incremento do histórico dos
dados de entrada na notação de transformada z. Cada uma das amostras
sucessivamente atrasadas é multiplicada pelo valor do coeficiente apropriado, h (m) ,
e os resultados, somados, geram um único valor representando a saída correspondente
à enésima amostra de entrada. O número de elementos de atraso, ou toques de filtro e
seus valores de coeficiente, determinam o desempenho do filtro.
A estrutura do filtro sugere os elementos físicos necessários para implementar esse
algoritmo por computação usando um DSP. Para o próprio cálculo, cada amostra de
saída requer um número de operações de acumulação múltipla igual ao comprimento
do filtro.

A linha de atraso para dados de entrada e a lista de valores de coeficientes requerem


áreas reservadas de memória no DSP para armazenar valores e coeficientes de
dados. A avançada arquitetura Harvard do DSP permite que os programadores
armazenem dados em Program Memory, assim como em Data Memory, e assim
executem dois acessos simultâneos à memória em cada ciclo a partir da SRAM
interna do DSP. Com a Memória de Dados contendo as amostras de entrada e a
Memória de Programa armazenando os valores dos coeficientes, um valor de dados e
um valor de coeficiente podem ser buscados em um único ciclo para cálculo.

Essa arquitetura de DSP favorece programas que usam buffer circular (discutido
brevemente na Parte 2 e mais adiante nesta parte). A implicação é que os ponteiros de
endereço precisam ser inicializados apenas no início do programa, e o mecanismo de
buffer circular garante que o ponteiro não deixe os limites de seu buffer de memória
designado - um recurso usado extensivamente no código de filtro FIR para ambos os
inputs linha de atraso e coeficientes. Uma vez que os elementos do programa tenham
sido determinados, o próximo passo é desenvolver o código fonte do DSP para
implementar o algoritmo.

Desenvolvendo Software DSP


O fluxo de desenvolvimento de software para a família ADSP-2100 consiste nas
seguintes etapas: descrição da arquitetura, geração do código fonte, validação de
software (depuração) e implementação de hardware. A Figura 2 mostra um ciclo de
desenvolvimento típico.
Figura 2. Fluxo de Desenvolvimento de Software.

Descrição da arquitetura: Primeiro, o usuário cria uma descrição de software do


sistema de hardware no qual o algoritmo é executado. O arquivo de descrição do
sistema inclui toda a memória disponível no sistema e todos os periféricos externos
mapeados na memória. Abaixo está um exemplo desse processo usando o ADSP-2181
EZ-Kit Lite.

Geração de código fonte: Passando da teoria para a prática, essa etapa - em que
uma ideia algorítmica é transformada em código que é executada no DSP -
geralmente é a etapa mais demorada do processo.Existem várias maneiras de gerar o
código-fonte. Alguns programadores preferem codificar seus algoritmos em uma
linguagem de alto nível, como C; outros preferem usar a linguagem assembly nativa
do processador. Implementações em C podem ser mais rápidas para o programador
desenvolver, mas o código DSP compilado não tem eficiência, não aproveitando ao
máximo a arquitetura de um processador.

O código de montagem, aproveitando ao máximo o design de um processador, produz


implementações altamente eficientes. Mas o programador precisa se familiarizar com
a linguagem de montagem nativa do processador. O mais eficaz é combinar C para
funções de controle de programa de alto nível e código de montagem para as partes de
tempo intensivo em matemática do sistema. Em qualquer caso, o programador deve
estar ciente das limitações do sistema do processador e das especificidades do
periférico. O exemplo de sistema de filtro FIR neste artigo usa a linguagem de
montagem nativa da família ADSP-2100.

Validação de software ("debugging"): Esta fase testa os resultados da geração de


código - usando uma ferramenta de software conhecida como simulador - para
verificar o fluxo lógico do programa e verificar se um algoritmo está funcionando
conforme o esperado. O simulador é um modelo do processador DSP que: a) fornece
visibilidade a todos os locais de memória e registros do processador; b) permite que o
usuário execute o código DSP continuamente ou uma instrução por vez; c) possa
simular dados de alimentação de dispositivos externos para o processador.

Implementação de hardware: Aqui o código é executado em um DSP real,


normalmente em várias fases: a) tryout em uma plataforma de avaliação como o
EZ-Kit Lite; b) emulação em circuito e c) geração de ROM de
produção. Tente fornece uma determinação rápida de ir / não-ir da operação do
programa; Essa técnica é o método de implementação usado neste artigo. Emulação
em circuito monitora a depuração de software no sistema, onde uma ferramenta como
o EZ-ICE ™ controla a operação do processador na plataforma de destino. Depois de
toda a depuração estar completa, ROM de inicialização do código final pode ser
gerado; serve como a implementação final de produção.

Trabalhando com o ADSP-2181 EZ-Kit Lite


Nosso exemplo do ciclo de desenvolvimento percorre o processo, usando o
ADSP-2181 EZ-Kit Lite (pacote de desenvolvimento ADDS-21xx-EZLITE) como o
hardware de destino para o algoritmo de filtro.O EZ-Kit Lite, uma plataforma de
demonstração e desenvolvimento de baixo custo, consiste em um processador
ADSP-2181 de 33 MHz, um codec de áudio estéreo AD1847 e uma EPROM com
soquete, que contém código de monitoração para baixar novos algoritmos para o DSP.
Conexão RS-232 (Figura 3).

Figur
a 3. Layout da placa EZ-Kit Lite.
Para completar a fase de descrição da arquitetura, é necessário conhecer a memória e
os periféricos mapeados na memória que o DSP tem disponível. Os programadores
armazenam essas informações em um arquivo de descrição do sistema para que o
software das ferramentas de desenvolvimento possa produzir o código apropriado
para o sistema de destino. O EZ-Kit Lite não precisa de memória externa ao DSP,
pois a memória disponível no chip é composta pelas 16.384 localizações da SRAM
Program Memory (PM) do ADSP-2181 e pelas 16.352 localizações da SRAM Data
Memory (DM). (32 locais de DM usados para registros de controle do sistema
não estão disponíveis para código de trabalho). Mais informações sobre o ADSP-2181,
a arquitetura do EZ-Kit Lite e tópicos relacionados, podem ser encontradas nos textos
mencionados no final deste artigo.

As informações disponíveis dos recursos do sistema são registradas em um arquivo de


descrição do sistema para uso pelas ferramentas de desenvolvimento da Família
ADSP-2100. Um arquivo de descrição do sistema tem uma extensão .SYS. A lista a
seguir mostra um arquivo de descrição do sistema [EZKIT_LT.SYS]:

.sistema EZ_LITE; / * dá um nome a este sistema * /

.adsp2181; / * especifica o processador * /

.mmap0; / * especifica que o sistema inicializa e que * /,

/ * A localização PM 0 está na memória interna * /

.seg / PM / RAM / ABS = 0 / código / dados int_pm [16384];

.seg / DM / RAM / ABS = 0 int_dm [16352];

.endsys; / * termina a descrição * /

A listagem declara 16.384 locais de PM como RAM, começando no endereço 0, para


permitir que os segmentos de código e os valores de dados sejam colocados
lá. Também declarados são 16.352 locais disponíveis de memória de dados como
RAM, começando no endereço 0. Como esses processadores usam uma arquitetura
Harvard com dois espaços de memória distintos, o endereço PM 0 é diferente do
endereço DM 0. O codec do ADSP-2181 EZ-Kit Lite é conectado ao DSP usando
uma porta serial, que não é declarada no arquivo de descrição do sistema. Para tornar
o arquivo de descrição do sistema disponível para outras ferramentas de software, o
utilitário do Construtor de Sistemas, BLD21, converte o arquivo .SYS em um arquivo
de arquitetura ou .ACH. A saída do System Builder é um arquivo chamado
EZKIT_LT.ACH.

Depois de escrever o código, o próximo passo é gerar um arquivo executável, ou seja,


transformar o código em instruções que o DSP pode executar. Primeiro monta o
código DSP. Isso converte o arquivo de programa em um formato que as outras
ferramentas de desenvolvimento podem processar. A montagem também verifica o
código em busca de erros de sintaxe. Em seguida, um link o código para gerar o
executável do DSP, usando a memória disponível que é declarada no arquivo de
arquitetura. O vinculador ajusta todos os códigos e dados do código-fonte no espaço
da memória; a saída é um arquivo executável DSP, que pode ser baixado para a placa
EZ-Kit Lite.

Gerando Código de Filtro


A parte 2 desta série [Analog Dialogue 31-2, página 14, Figura 6] introduziu uma
pequena listagem de código assembly para um filtro FIR. Aqui, esse código é
aumentado para incorporar alguns recursos específicos do EZ-Kit Lite,
especificamente a inicialização de codecs e E / S de dados. Os elementos do algoritmo
de filtro principal (acumular-se multiplamente, endereçamento de dados usando
buffers circulares para dados e coeficientes e confiança na eficiência do loop de
sobrecarga zero) não são alterados.

Os dados de entrada serão amostrados usando o codec AD1847 on-board, que possui
taxa de amostragem programável, ganho de entrada, atenuação de saída, seleção de
entrada e mixagem de entrada. Sua natureza programável torna o sistema flexível,
mas também adiciona uma tarefa de programação para inicializá-lo para o sistema
DSP.

Acessando dados
Para este exemplo, uma série de palavras de controle para o codec - a ser definido no
início do programa na primeira seção da listagem - irá inicializá-lo para uma taxa de
amostragem de 8 kHz, com valores moderados de ganho em cada entrada
canais. Como o AD1847 é programável, os usuários geralmente reutilizam os
segmentos de código de interface e inicialização, alterando apenas os valores de
registro específicos para diferentes aplicativos. Este exemplo adicionará o segmento
de filtro específico a um segmento de código existente encontrado no software EZ-Kit
Lite.

Este código de interface declara duas áreas na memória a serem usadas para E / S de
dados: "tx_buf", para dados a serem transmitidos para fora do codec e "rx_buf", onde
os dados recebidos são recebidos.Cada uma dessas áreas de memória, ou buffers,
contém três elementos, uma palavra de controle ou status, dados do canal esquerdo e
dados do canal direito. Para cada período de amostragem, o DSP receberá do codec
uma palavra de status, dados do canal esquerdo e dados do canal direito. Em cada
período de amostra, o DSP deve fornecer ao codec um transmite palavra de
controle, dados do canal esquerdo e dados do canal direito. Nesta aplicação, as
informações de controle enviadas para o codec não serão alteradas, então a primeira
palavra no buffer de dados de transmissão será deixada como está. Vamos supor que a
fonte é um microfone monofônico, usando o canal direito (sem preocupação com
dados de entrada do canal esquerdo).

Usando o programa shell de E / S encontrado no software EZ-Kit Lite, precisamos


estar envolvidos apenas com a seção de código "input_samples". Esta seção de código
é acessada quando novos dados são recebidos do codec pronto para ser processado. Se
apenas os dados do canal direito forem necessários, precisamos ler os dados
localizados na memória de dados no local rx_buf + 2 e colocá-los em um registrador
de dados para serem alimentados no programa de filtragem.

Os dados que chegam do codec precisam ser alimentados no algoritmo de filtro por
meio da linha de atraso de entrada, usando a capacidade de buffer circular do
ADSP-2181. O comprimento da linha de atraso de entrada é determinado pelo número
de coeficientes usados para o filtro. Como o buffer de dados é circular, o valor de
dados mais antigo no buffer será sempre que o ponteiro estiver apontando após o
último acesso ao filtro (Figura 4). Da mesma forma, os coeficientes, sempre acessados
na mesma ordem todas as vezes através do filtro, são colocados em um buffer
circular na Memória de Programa.

Figura 4. Exemplo de Uso de Buffers Circulares para Entrada de Dados do


Filtro.

Código de Algoritmo
Para operar nos dados recebidos, a seção de código publicada na última parcela pode
ser usada com poucas modificações. Para implementar esse filtro, precisamos usar a
unidade computacional de multiplicação / acumulação (MAC) e os geradores de
endereço de dados.

O MAC do ADSP-2181 armazena o resultado em um registrador de 40 bits (32 bits


para o produto de 2 palavras de 16 bits e 8 bits para permitir que a soma se expanda
sem transbordar). Isso permite que os valores dos filtros intermediários cresçam e
encolham conforme necessário, sem corromper os dados. O segmento de código
utilizado é genérico (isto é, pode ser usado para qualquer filtro de
comprimento);assim, os bits de saída extras do MAC permitem que filtros arbitrários
com dados desconhecidos sejam executados com pouco medo de perder dados.

Para implementar o filtro FIR, a operação de multiplicação / acumulação é repetida


para todos os toques do filtro em cada ponto de dados. Para fazer isso (e estar pronto
para o próximo ponto de dados), a instrução MAC é escrita na forma de um loop. O
recurso de loop de sobrecarga zero do ADSP-21xx permite que a instrução MAC seja
repetida para um número especificado de contagens sem intervenção de
programação. Um contador é configurado para o número de toques menos um, e o
mecanismo de loop decrementa automaticamente o contador para cada operação de
loop. Definir o contador de loops como "taps-1" garante que os ponteiros de dados
acabem no local correto após a conclusão da execução e permite que a operação final
do MAC inclua o arredondamento. Como o AD1847 é um codec de 16 bits, o MAC
com arredondamento fornece um resultado estatisticamente imparcial arredondado
para o valor de 16 bits mais próximo. Este resultado final é gravado no codec.

Para uma execução ideal do código, todo ciclo de instrução deve executar um cálculo
matemático significativo. Os ADSP-21xxs fazem isso com instruções multifuncionais:
o processador pode executar várias funções no mesmo ciclo de instrução. Para o
código de filtro FIR, cada operação de acumulação de multiplicação (MAC) pode ser
executada em paralelo com dois acessos de dados, um da Memória de Dados, um da
Memória de Programa. Esse recurso significa que, em cada iteração de loop, uma
operação MAC está sendo executada. Ao mesmo tempo, o próximo valor e
coeficiente de dados estão sendo buscados e o contador é decrementado
automaticamente. Tudo sem perder tempo mantendo loops.

Como o código do filtro é executado para cada amostra de dados de entrada, a saída
do loop MAC será gravada no buffer de dados de saída, tx_buf. Embora este
programa lide apenas com dados de entrada de canal único, o resultado será gravado
em ambos os canais gravando nos endereços do buffer de memória tx_buf + 1 e
tx_buf + 2.

A listagem final do código-fonte é mostrada na página 15. O próprio algoritmo de


filtro está listado em "Rotinas de serviço de interrupção". O restante do código é
usado para inicialização de codec e DSP e interrompe a definição de rotina de
serviço. Esses tópicos serão explorados em futuras parcelas desta série.

O EZ-Kit Lite
O software de monitor baseado em Windows fornecido com o EZ-Kit Lite permite
carregar um arquivo executável no ADSP-2181 na placa EZ-Kit Lite. Isso é feito
através do menu suspenso "Carregando", selecionando "Baixar programa do usuário e
Ir" (Figura 5). Isso fará o download do programa de filtro para o ADSP-2181 e
iniciará a execução do programa.
Figura 5. Menu de download do EZ-Kit Lite.

Revise e visualize
O objetivo deste artigo era delinear os passos de uma descrição do algoritmo para um
programa executável do DSP que poderia ser executado em uma plataforma de
desenvolvimento de hardware. Os problemas introduzidos incluem fluxo de
desenvolvimento de software, descrição de arquitetura, geração de código fonte, E / S
de dados e a plataforma de hardware EZ-Kit Lite.

Há muitos níveis de detalhes associados a cada um desses tópicos que este breve
artigo não poderia fazer justiça. Mais informações estão disponíveis nas referências
abaixo. A série continuará a desenvolver este aplicativo com tópicos adicionais. O
próximo artigo examinará os problemas de entrada / saída de dados (I / O) com mais
detalhes através da estrutura de interrupção do processador e discutirá recursos
adicionais do algoritmo de filtro simples.

FIR Filtrar listagem de código para EZ-Kit


Lite
/ *************************************************
*************

*
* hello81.dsp - arquivo de modelo para a placa 2181 ez-kit lite

* Este programa de amostra está organizado nas seguintes seções:

* Montar constantes de tempo (system.h)

* Interromper a tabela de vetores

* Intialização do ADSP 2181 (init1847.dsp)

* Intialização de codec ADSP 1847 (init1847.dsp)

* Interromper rotinas de serviço

* Este programa implementa um simples 'talk-through' com o codec


AD1847.

* As rotinas de inicialização foram colocadas no arquivo


init1847.dsp. este

* O arquivo contém a tabela de vetores de interrupção, o loop


principal 'fictício' e o

* interromper rotinas de serviço para o botão de pressão e a porta


serial 0 receber.

* O botão de pressão (IRQE) faz com que o LED na placa EZ-Kit


alterne

* com cada botão, pressione.

* Os parâmetros que controlam a taxa de amostragem, ganhos, etc.,


estão contidos no

* arquivo init1847.dsp. A porta serial 0 é usada para se comunicar


com o AD1847.

* As interrupções de transmissão são usadas para configurar o codec,


então elas são
* desativado e as interrupções de recebimento são usadas para
implementar o 'talk-through'

* áudio.

* As definições para os registros de controle mapeados na memória


estão contidas

* o arquivo: system.h

* O aplicativo pode ser construído por:

* asm21 -c -l -2181 ola81

* asm21 -c -l -2181 init1847

* ld21 ola81 init1847 -a 2181 -e ola81 -g -x

**************************************************
******** /

.module / RAM / ABS = 0 EzHello;

#incluir

#define toques 255 / * comprimento da torneira do filtro * /

.var / dm / circ filt_data [toques]; / * buffer de dados de entrada * /

.var / pm / circ filt_coeffs [toques]; / * buffer de coeficiente * /

.init filt_coeffs :; / * inicializar coeficientes * /

.external rx_buf, tx_buf;

.external init_cmds, stat_flag;

.external next_cmd, init_1847, init_system_regs, init_sport0;


/ *************************************************
*********

* Interromper a tabela de vetores

**************************************************
******** /

iniciar salto; rti; rti; rti; / * 00: reset * /

rti; rti; rti; rti; / * 04: IRQ2 * /

rti; rti; rti; rti; / * 08: IRQL1 * /

rti; rti; rti; rti; / * 0c: IRQL0 * /

ar = dm (stat_flag); / * 10: SPORT0 tx * /

ar = passar ar;

se eq rti;

salte next_cmd;

jump input_samples; / * 14: SPORT1 rx * /

rti; rti; rti;

irqe salto; rti; rti; rti; / * 18: IRQE * /

rti; rti; rti; rti; / * 1c: BDMA * /

rti; rti; rti; rti; / * 20: SPORT1 tx ou IRQ1 * /

rti; rti; rti; rti; / * 24: SPORT1 rx ou IRQ0 * /

rti; rti; rti; rti; / * 28: temporizador * /

rti; rti; rti; rti; / * 2c: desligar * /

/ *************************************************
***********

* Intialização ADSP 2181

**************************************************
********** /
começar:

i0 = ^ rx_buf; / * Lembre-se de que o autobuffering de codec usa i0


e i1 !! * /

l0 =% rx_buf;

i1 = ^ tx_buf;

l1 =% tx_buf;

i3 = ^ init_cmds; / * i3 pode ser usado para outra coisa após o codec


init * /

l3 =% init_cmds;

m0 = 0;

m1 = 1;

/ * inicializar porta serial 0 para comunicação com o codec AD1847 *


/

chame init_sport0;

/ * inicializa os outros registros do sistema, etc. * /

chame init_system_regs;

/ * inicializar o codec AD1847 * /

chame init_1847;

ifc = b # 00000011111111; / * limpar qualquer interrupção pendente


*/

nop; / * existe uma latência de 1 ciclo para ifc * /

/ * ponteiros de configuração para dados e coeficientes * /

i2 = ^ filt_data;

l2 =% filt_data;

i5 = ^ filt_coefs;

m5 = 1;
l5 =% filt_coefs;

imask = b # 0000110000; / * enable rx0 interrupção * /

/ * ||||||||| + | cronômetro

|||||||| + - | SPORT1 rec ou IRQ0

||||||| + - | SPORT1 trx ou IRQ1

|||||| + --- | BDMA

||||| + ---- | IRQE

|||| + ----- | SPORT0 rec

||| + ------ | SPORT0 trx

|| + ------- | IRQL0

| + -------- | IRQL1

+ --------- | IRQ2

*/

/ * ------------------------------------------------ ----------------------

- aguarde a interrupção e faça um loop para sempre

-------------------------------------------------- -------------------- * /

conversação: ocioso;

pular talkthru;

/ *************************************************
*************

* Interromper rotinas de serviço

**************************************************
************ /

/ * ------------------------------------------------ ----------------------

- Filtro FIR
-------------------------------------------------- -------------------- * /

input_samples:

ena sec_reg; / * use banco de registradores de sombra * /

ax0 = dm (rx_buf + 1); / * ler dados do conversor * /

dm (i2, m1) = ax0; / * escreve novos dados na linha de atraso,


ponteiro

agora apontando para dados mais antigos * /

cntr = taps - 1;

mr = 0, mx0 = dm (i2, m1), my0 = pm (i5, m5); / * clear accumulator,


obtenha primeiro

dados e valor do coeficiente * /

filt_loop até ce; / * loop de zero sobrecarga de configuração * /

filt_loop: mr = sr + mx0 * my0 (ss), mx0 = dm (i2, m1), my0 = pm


(i5, m5);

/ * MAC e duas buscas de dados * /

mr = mr + mx0 * my0 (rnd); / * final multiplicar, arredondar para


resultado de 16 bits * /

se mv saat mr; / * verifique se há estouro * /

dm (tx_buf + 1) = mr1;

dm (tx_buf + 2) = mr1; / * dados de saída para ambos os canais * /

rti;

.endmod;
DSP 101 Part 4:
Programming
Considerations for
Real-time I/O
by David Skolnick and Noam Levine Download PDF

So far, this series has introduced the following topics:

 Part 1 (vol. 31-1): DSP architecture and DSP advantages over traditionally
analog circuitry
 Part 2 (vol. 31-2): digital filtering concepts and DSP filtering algorithms
 Part 3 (vol. 31-3): implementation of a finite-impulse- response (FIR) filter
algorithm and an overview of a demonstration hardware platform, the
ADSP-2181 EZ-Kit Lite.

Now, we look more closely at DSP programming concerns that are unique to
real-time systems. This article focuses on how to develop algorithms for DSP systems
with a variety of I/O interfaces.

What does "real-time" mean? In an analog system, every task is performed in "real
time" with continuous signals and processing. In a digital signal-processing (DSP)
system, signals are represented with sets of samples, i.e., values at discrete points in
time. Thus the time for processing a given number of samples in a DSP system can
have an arbitrary interpretation in "real time", depending on the sampling rate. The
first article in this series introduces the concept of sampling and the Nyquist
criterion–that in real-time applications, the sampling frequency must be at least twice
the frequency of the highest frequency component of interest in the (analog) signal
(Nyquist rate). The time between samples is referred to as the sampling interval. To
consider a system as operating in "real time," all processing of a given set of data (one
or more samples, depending on the algorithm) must be completed before new data
arrives.

This definition of real time implies that, for a processor operating at a given clock rate,
the speed and quantity of the input data determines how much processing can be
applied to the data without falling behind the data stream. The idea of having a limited
amount of time with which to handle data may seem odd to analog designers because
this concept does not have a parallel in analog systems. In analog systems, signals are
processed continuously. The only penalty in a slow system is limited frequency
response. By comparison, digital systems process parts of the signal, enough for very
accurate approximations, but only within a limited block of time. Figure 1 shows a
comparison. Real-time DSP can be limited by the amount of data or type of
processing that can be completed within the algorithm's time budget. For example, a
given DSP processor handling data values sampled at, say, 48-kHz (audio signals),
has less time to process those data values, including execution of all necessary tasks,
than one sampling 8-kHz voice-band data.

In the filter example described earlier in this series, the input sampling rate is 8 kHz.
For the DSP in the example to keep up with real-time data, all processing has to be
done within a time budget of 1/(8 kHz), or 125 µs. On a 33-MHz digital
signal-processor (30ens per cycle), the time budget provides 125 µs/30 ns, or 4166
instruction cycles, to complete processing and any other required tasks.

Since there is a finite amount of time that can be budgeted to perform any given
algorithm, managing time is a central part of DSP system software design. Time
management strategy determines how the processor gets notified about events,
influences data handling, and shapes processor communications.

Figure 1. Comparison of
analog and digital signal processing. a. Analog: A response value
corresponds to each data value at all instants of time. b. Digital: For
each sample, the data must be transferred in and processed, an event marks
the end of processing (control), and extra time may be necessary for other
tasks within the cycle after the designated process occurs.
Event Notification: Interrupts: One can program a DSP to process data using one of
several strategies for handling the "event," the arrival of data. A status bit or flag pin
could be read periodically to determine whether new data is available. But–"polling"
wastes processor cycles. The data may arrive just after the last poll, but it can't make
its presence known until the next poll. This makes it difficult to develop real-time
systems.

The second strategy is for the data to interrupt the processor on arrival. Using
interrupts to notify the processor is efficient, though not as easy to program; clock
cycles can be wasted during the wait for an interrupt. Nevertheless, event-driven
interrupt programming being well-suited to processing real-world signals promptly,
most DSPs are designed to deal efficiently with them. In fact, they are designed to
respond very quickly to interrupts. The ADSP-2181's response time to an interrupt is
about three processor cycles; i.e., within 75 ns the DSP has stopped doing what it was
doing and is handling the interrupt event (vector).
In many DSP-based systems, the interrupt rates, based on the input data sampling rate,
are often totally unrelated to the DSP's clock rate. In the FIR example seen earlier in
this series, the processor is interrupted at 125-µs intervals to receive new data.

Interrupt Handling and Interrupt Vectors: Because interrupt processing is such a


vital element in DSP systems, processors typically have built-in hardware
mechanisms to handle interrupts efficiently. Hard-wired mechanisms are more
efficacious than software alone because a DSP's interrupt service routines (ISRs) may
have to meet all of the following demands:

 Fast context switching–switch from working on one task and its data (a
context) to another context without the time loss and complication
associated with writing programs to save register contents and chip status
information.
 Nested-interrupt handling–handle multiple interrupts of different priorities
"simultaneously." The DSP handles one interrupt at a time, but an interrupt
of higher priority can take precedence over the handling of a lower-priority
interrupt.
 Continue to accept data/record status–while the DSP services an interrupt,
events keep on occurring in the real world and data keeps on arriving. To
keep up with the "real-world," the DSP must record these events and accept
the data–then process them when it has finished servicing the interrupt.

On Analog Devices DSPs, fast context switching is accomplished using two sets of
data registers. Only one set is active at a time, containing all the data in process during
that context. When servicing an interrupt, the computer can switch from the active to
the alternate set without having to temporarily save the data in memory. This
facilitates rapid switching between tasks.

To handle multiple interrupts, Analog Devices DSPs record their state for each one.
Processor state information is kept on a set of status "stacks" located in the DSP's
Program Sequencer. A "stack" consists of a set of hardware registers. Current status
information is "pushed" onto the stack when an event occurs. This stack mechanism
also allows interrupts to be nested; one with higher priority can interrupt one with
lower priority.

Two hardware features, interrupt latch and automated I/O, let Analog Devices DSPs
stay abreast of the "real world" while processing an interrupt. The latch keeps the
DSP from missing important events while servicing an interrupt. The other feature,
comprising various forms of automated I/O (including serial ports, DMA,
autobuffering, etc.) lets external devices pump data into the DSP's memory without
requiring intervention from the DSP. So no data is missed while the DSP is "busy."

When an interrupt request is generated, by an external source or an internal resource,


the DSP processor automatically stores its current state of operation, and prepares to
execute the interrupt routine. Interrupt routines are dispatched from an interrupt vector
table. An interrupt vector table is an area in Program Memory with instruction
addresses assigned to particular DSP interrupt functions. For example, in the table
below, a Transmit (Tx) interrupt at serial port 1 (SPORT1) of an ADSP-2181
processor will cause the next instruction to be executed at program memory (PM)
location 0x0020, followed by the contents of the next three locations, through 0x0023
(the interrupt routine). As the 12 items in the table indicate, an ADSP-2181 can
handle interrupts from 11 locations (external hardware, DMA ports, and the serial
ports) and the processor Reset. The table lists the programmed instructions assigned
to each interrupt vector source in memory locations 0x0000 to 0x002F for an FIR
filter program.

Jump start; nop; nop; nop; /* PM(0x0000-03): Reset vector */


rti; nop; nop; nop; /* PM(0x0004-07): IRQ2 vector */
rti; nop; nop; nop; /* PM(0x0008-0B): IRQL1 vector */
rti; nop; nop; nop; /* PM(0x000C-0F): IRQL0 vector */
ar = dm(stat_flag); ar = pass ar; if eq_rti; jump next_cmd;
/* PM(0x0010-13): SPORT0 Tx vector */
jump input_samples; nop; nop; nop;
/* PM(0x0014-17): SPORT0 Rx vector */
jump irqe; nop; nop; nop; /* PM(0x0018-1B): IRQE vector */
rti; nop; nop; nop; /* PM(0x001C-1F): BDMA vector */
rti; nop; nop; nop; /* PM(0x0020-23): SPORT1 Tx vector */
rti; nop; nop; nop; /* PM(0x0024-27): SPORT1 Rx vector */
rti; nop; nop; nop; /* PM(0x0028-2B): Timer vector */
rti; nop; nop; nop; /* PM(0x002C-2F): Powerdown vector */

Each interrupt vector has four instruction locations. Typically, these instructions will
cause the processor to jump to another area of memory in order to process the data, as
is shown in the Reset (at 0x0000), SPORT0 Rx (0x0014), and IRQE (0x0018)
interrupt vectors. If there are just a few steps–such as reading a value, checking status,
or loading memory–that can be done within the four available instruction locations,
they are programmed directly, as shown in the SPORT0 Tx vector (0x0010-13). Any
unused interrupt vectors call for return from interrupt (rti), with three nop (no
operation) instructions.

The nop instructions serve as place holders–instruction space used to ensure that the
correct interrupt action lines up with the hardware-specified interrupt vector. The rti
instruction at the beginning of each unused vector location is both placeholder and
safety valve. If an unused interrupt is mistakenly unmasked or inadvertently triggered,
"rti" causes a return to normal execution.

Data I/O
In DSP systems, interrupts are typically generated by the arrival of data or the
requirement to provide new output data. Interrupts may occur with each sample, or
they may occur after a frame of data has been collected. The differences greatly
influence how the DSP algorithm deals with data.

For algorithms that operate on a sample-by-sample basis, DSP software may be


required to handle each incoming and outgoing data value. Each DSP serial port
incorporates two data I/O registers, a receive register (Rx), and a transmit register
(Tx). When a serial word is received, the port will typically generate a Receive
interrupt. The processor stops what it is doing, begins executing code at the interrupt
vector location, reads the incoming value from the Rx register into a processor data
register, and either operates on that data value or returns to its background task. In the
table above, the computer jumps to a program segment, "input_samples", performs
whatever instructions are programmed in that segment, and returns from the interrupt,
either directly or via a return to the interrupt vector.

To transmit data, the serial port can generate a Transmit interrupt, indicating that new
data can be written to the SPORT Tx register. The DSP can then begin code execution
at the SPORT Tx interrupt vector and typically transfer a value from a data register to
the SPORT Tx register. If data input and output are controlled by the same sampling
clock, only one interrupt is necessary. For example, if a program segment is initiated
by Receive interrupt timing, new data would be read during the interrupt routine; then
either the previously computed result, which is being held in a register, would be
transmitted, or a new result would be computed and immediately transmitted–as the
final step of the interrupt routine.

All of these mechanisms help a DSP to approach the ability to emulate what an analog
system does naturally–continuously process data in real time–but with digital
precision and flexibility. In addition, in an efficiently programmed digital system,
spare processor cycles left between processing data sets can be used to handle other
tasks.

Programming Considerations
In a "real-time" system, processing speed is of the essence. By using SPORT
autobuffering, no time is lost to data I/O. Instead, the data management goal is to
make sure that the selected address points to the new data.

In the FIR filter example (Analog Dialogue 31-3, page 15), a SPORT Receive
interrupt request is generated when the input autobuffer is full, meaning that the DSP
has received three data words: status, left channel data, and right channel data. Since
this simplified application uses single-channel data, only the data value that resides at
location rx_buf+1 is used by the algorithm.

Filter Algorithm Expansion In other applications, the data handling can be more
involved. For example, if the FIR filter of the example were expanded to a
two-channel implementation, the core DSP algorithm code would not have to change.
The code relating to data handling, however, would have to be modified to account
for a second data stream and a second set of coefficients.

In the filter code, two new buffers in memory would be required to handle both the
additional data stream and the additional set of coefficients. The core filter loop may
be isolated as a separate "callable" function. This technique lets the same code be
used, regardless of the input data values. Benefits of this programming style include
readable code, re-usable algorithms, and reduced code size. If a modular approach is
not taken, the filter loop would have to be repeated, using additional DSP memory
space.
The SPORT Receive interrupt routine would then consist of the setting of pointer and
calling the filter. The revised filter routine is shown in the following listing:

Filter: cntr = taps - 1;


mr = 0, mx0 = dm(i2,m1), my0 = pm(i5,m5);
/* clear accumulator, get first data
and coefficient value */
do filt_loop until ce; /* set-up zero-overhead loop */
filt_loop: mr = mr + mx0*my0(ss), mx0 = dm(i2,m1),
my0 = pm(i5,m5); /* MAC and two data fetches */
mr = mr + mx0 * my0 (rnd); /* final multiply, round to 16-bit
result */
if mv sat mr; / * check for overflow*/
rts; /* return */

It's important to note that the only modifications to the core filter loop were the
addition of a label, "Filter:" at the beginning of the routine, and the addition of an
"rts" (return from subroutine) instruction at the end. These additions change filter
code from a stand-alone routine into a subroutine that can be called from other
routines. No longer a single-purpose routine, it has become a re-usable, callable
subroutine.

With the core filter set up as a callable subroutine, the two-channel data handling
requirements can now be addressed. To simplify some of the programming issues, this
example assumes that both the left and right channels use the same filter coefficients.

In the third installment of this series, the entire filter application assembly code was
displayed. At the top of the code listing, all of the required memory buffers were
declared. To expand the filter application to handle two channels of data, the required
new variables and buffers need to be declared. For the incoming data, the buffer
declaration,

.var/dm/circ_filt_data[taps]; /* input data buffer */

would need to be replaced with two buffers, declared as

.var/dm/circ_filt1_data[taps]; /* left channel input data buffer */


.var/dm/circ_filt2_data[taps]; /* right channel input data buffer */

Because both channels are to have the same filter coefficients applied to them, the
data buffers are of equal length.

The filter loop subroutine expects certain data and coefficient values to be accessed
using particular address registers. Specifically, address register I2 must point to the
oldest data sample, and I5 must point to the proper coefficient value prior to the filter
routine being called.

Because the filters for both the left and right channel will be sharing the same
memory pointers, there has to be a mechanism for differentiating the two data streams.
For the data pointer, I2, two new variables need to be defined, "filter1_ptr" and
"filter2_ptr."

These locations in memory are going to be used to store address values appropriate
for each data stream. The circular buffering capability of the ADSP-2181 is used to
ensure that the data pointer is always in the correct place in the buffer whenever the
filter is executed. Because the subroutine is now dealing with two buffers, the pointer
locations need to be saved when processing for each channel is completed.

To set up the pointers, two variables in data memory need to be declared as follows:

.var/dm filter1_ptr; /* data pointer for left channel data */


.var/dm filter2_ptr; /* data pointer for right channel data */

These variable then need to be initialized with the starting address of each of the data
buffers;

.init filter1_ptr: ^filt1_data; /* initialize starting point,


left channel */
.init filter2_ptr: ^filt2_data; /* initialize starting point,
right channel */

The DSP assembler software recognizes the symbol "^" to mean "address of." The
DSP linker software fills in the appropriate address value. In this way, the pointer
variables in the executable program are initialized with the starting addresses of the
appropriate memory buffers.

The following listing shows how the FIR Filter interrupt routine uses these new
memory elements. The original Filter subroutine from the 3rd installment has been
modified to provide two separate channels of filtering. Instead of launching directly
into the filter calculation, the routine must first load the appropriate data pointer. The
filter routine is then called, and the resulting output is placed in the correct location
for transmission.

/*--------------------FIR Filter--------------------*/
input_samples:
ena sec_reg; /* use shadow register bank */

/* set up for filter 1 */


i2 = dm(filter1_ptr); /* set data pointer for filter 1 */
ax0 = dm(rx_buf + 1); /* read left channel data */
dm(i2,m1) = ax0; /* write new data into delay line,
pointer now pointing to oldest data */

call filter; /* perform the first filter for left


channel data */

dm(tx_buf+1) = mr1; /* write left-channel output data */


dm(filter1_ptr) = i2; /* save updated filter1 data pointer */
/* set up for filter 2 */
i2 = dm(filter2_ptr); /* set data pointer for filter 2 */
ax0 = dm(rx_buf + 2); /* read right channel data */
dm(i2,m1) = ax0; /* write new data into delay line,
pointer now pointing to oldest data */

call filter; /* perform the filter again for the


right channel data */

dm(tx_buf+2) = mr1; /* write right channel output data */


dm(filter2_ptr) = i2; /* save updated filter2 data pointer */

rti; /* return from interrupt */

Because the core filter algorithm no longer handles data I/O, this subroutine can be
expanded to more channels of filtering by merely adding more pointer variables and
declaring more buffer space (as long as sufficient memory exists!) Similarly, different
coefficients can be used for the two filters by setting up variables that contain
coefficient-buffer pointer information. In either case, the filter algorithm does not
need to be altered. By using this style of modular programming, the user can build up
a library of callable DSP functions. Differences for particular systems can thus be
reduced to data-handling issues rather than the development of new algorithms. While
this programming style does not necessarily allow the algorithm to perform its task
more quickly, the system designer has more flexibility in establishing how data flows
through the system.

Real-Time Interface Issues: So far, we have examined how real-time programming


in embedded systems relies on rapid interrupt response, efficient data handling, and
fast program execution. In addition, the flow of data into and out of the processor also
influences how well the system will work in a real-time embedded environment.

The primary data flows into and out of a digital signal processor can be both parallel
and serial. Parallel transfers are typically at least as wide as the native data word of
the processor's architecture (16 bits for an ADSP-2100 Family processor, 32 bits for
the SHARC®). Parallel transfers occur via the external memory bus or external host
interface bus of the processor. Serial data transfers require considerably fewer
interconnections; they are frequently used to communicate with data converters.

Serial Interface: Ease of hardware interfacing is an important element of efficient


DSP system implementation. The ADSP-2181 EZ-Kit Lite system uses an AD1847
serial codec (COder/DECoder). Serial codecs permit data transfers via a serial port
(SPORT) on the DSP. This serial port is not an RS-232 PC-style asynchronous serial
port; it is a 5-wire synchronous interface that passes bit-clock, Receive-data,
Transmit-data, and frame-synchronization signals. Major benefits of serial interfaces
are low pin count and ease of hardware hookup. The AD1847 requires only 4 signals
to interface to the DSP: serial clock, Receive data, Transmit data, and Receive
frame-synchronization signal. The serial data stream is time-division multiplexed
(TDM), meaning that the same physical line can carry more than one type of
information in serial order. In the case of the AD1847 application on EZ-Kit Lite,
initiated in the last issue, the serial line carries both left- and right-channel audio
information, along with codec control and status information.

As noted earlier, the processor has various means for handling this data. SPORT
Interrupts are generated automatically by the serial port hardware for either Receive
or Transmit data and for either a single word or a block of words (Figure 2). Serial
interfacing between digital signal processor and I/O device

Figure 2. Serial interfacing


between digital signal processor and I/O device.
Parallel Interface: Even with a serial bit clock running as fast as the DSP processor, a
serial interface trades data transfer speed for simplicity of wiring, transferring a data
word at a fraction of the DSP processor speed. For system performance that requires
higher data rates, a parallel interface can be used. When interfacing in parallel, the
DSP exercises its external data and address busses to read or write data to a peripheral
device. On the ADSP-2181, the buses can interface with up to 16 bits of data.

Parallel data transfer is always faster than serial transfers. The DSP can perform an
external access every processor cycle, but this requires really fast parallel peripherals
that can keep up with it, such as fast SRAM chips. Parallel data transfers with other
entities usually occur at less than one per processor cycle.

Interrupt handling is different for the serial and parallel interfaces. Since the external
data bus of the DSP processor is a general-purpose entity handling all sorts of data, it
does not have dedicated signal lines for interrupt generation and control; however,
other DSP resources are available. On the ADSP-2181, several external hardware
interrupt lines, such as the one for I/O memory select, are available for triggering by
an external device, such as an A/D converter or codec. Such an interface is shown in
Figure 3, involving a parallel device and the ADSP-2181 DSP. Parallel I/O interfacing
for a DSP
Figure 3. Parallel I/O interfacing
for a DSP.
When responding to the interrupt for parallel data, the processor reads the appropriate
source and typically places that data value in memory, by executing instructions
similar to those shown here:

irq2_svc: ax0 = IO(ad_converter); dm(i2,m1) = ax0; rti;


"ad_converter" is a previously defined address in I/O space.

REVIEW AND PREVIEW


The goal of this article has been to detail the programming concerns that DSP
developers face when handling I/O and other events in real-time systems. Issues
introduced include real-time data (samples and frames), interrupts and
interrupt-handling, automated I/O, and generalizing routines to make callable
subroutines. This brief article could not do justice to the many levels of detail
associated with each of these topics. Further information is available in the references
below. Future topics in this series will continue to build on this application. The next
article will add more features to our growing example program and describe software
validation (i.e., debugging) techniques.

**

DSP 101 Parte 4:


Considerações de
programação para E / S
em tempo real
de David Skolnick e Noam Levine baixar PDF

Até agora, esta série introduziu os seguintes tópicos:


 Parte 1 (vol. 31-1) : Arquitetura do DSP e vantagens do DSP em relação aos
circuitos tradicionalmente analógicos
 Parte 2 (vol. 31-2) : conceitos de filtragem digital e algoritmos de filtragem
DSP
 Parte 3 (vol. 31-3) : implementação de um algoritmo de filtro de resposta de
impulso finito (FIR) e uma visão geral de uma plataforma de demonstração de
hardware, o ADSP-2181 EZ-Kit Lite.
Agora, analisamos mais de perto as preocupações de programação do DSP exclusivas
dos sistemas em tempo real. Este artigo se concentra em como desenvolver algoritmos
para sistemas DSP com uma variedade de interfaces de E / S.

O que significa "tempo real"? Em um sistema analógico, toda tarefa é executada


em "tempo real" com sinais e processamento contínuos. Em um sistema de
processamento de sinal digital (DSP), os sinais são representados com conjuntos de
amostras, isto é, valores em pontos discretos no tempo. Assim, o tempo para processar
um dado número de amostras em um sistema DSP pode ter uma interpretação
arbitrária em "tempo real", dependendo da taxa de amostragem. O primeiro artigo
desta série introduz o conceito de amostragem e o critério Nyquist - que em
aplicações em tempo real, a frequência de amostragem deve ser pelo menos o dobro
da frequência do componente de maior frequência de interesse no sinal (analógico)
(taxa de Nyquist) . O tempo entre as amostras é referido como o intervalo de
amostragem. Para considerar um sistema como operando em "tempo real", todo o
processamento de um dado conjunto de dados (uma ou mais amostras, dependendo do
algoritmo) deve ser completado antes que novos dados cheguem.

Essa definição de tempo real implica que, para um processador operando em um


determinado clock, a velocidade e a quantidade dos dados de entrada determinam
quanta processamento pode ser aplicado aos dados sem ficar atrás do fluxo de
dados. A ideia de ter um período de tempo limitado para lidar com dados pode parecer
estranha para projetistas analógicos porque esse conceito não tem um paralelo em
sistemas analógicos. Nos sistemas analógicos, os sinais são processados
continuamente. A única penalidade em um sistema lento é a resposta de
freqüência limitada. Por comparação, os sistemas digitais processam partes do sinal, o
suficiente para aproximações muito precisas, mas apenas dentro de um período
limitado de tempo. A figura 1 mostra uma comparação. O DSP em tempo real pode
ser limitado pela quantidade de dados ou tipo de processamento que pode ser
concluído dentro do orçamento de tempo do algoritmo. Por exemplo, um determinado
processador DSP que manipula valores de dados amostrados a, digamos, 48 kHz
(sinais de áudio), tem menos tempo para processar esses valores de dados, incluindo a
execução de todas as tarefas necessárias, do que dados amostrais de banda de 8 kHz.

No exemplo de filtro descrito anteriormente nesta série, a taxa de amostragem de


entrada é 8 kHz. Para que o DSP no exemplo acompanhe os dados em tempo real,
todo o processamento deve ser feito dentro de um orçamento de tempo de 1 / (8 kHz)
ou 125 µs. Em um processador de sinal digital de 33 MHz (30ens por ciclo), o
orçamento de tempo fornece 125 µs / 30 ns, ou 4166 ciclos de instruções, para
concluir o processamento e quaisquer outras tarefas necessárias.
Como há uma quantidade finita de tempo que pode ser orçada para executar qualquer
algoritmo, o gerenciamento de tempo é uma parte central do design do software do
sistema DSP. A estratégia de gerenciamento de tempo determina como o processador
é notificado sobre eventos, influencia o tratamento de dados e modela as
comunicações do processador.

Figura 1. Comparação do
processamento de sinais analógico e digital. uma. Analógico: Um valor de
resposta corresponde a cada valor de dados em todos os instantes de
tempo. b. Digital: Para cada amostra, os dados devem ser transferidos e
processados, um evento marca o final do processamento (controle) e o tempo
extra pode ser necessário para outras tarefas dentro do ciclo após a
ocorrência do processo designado.

Notificação de evento: interrupções: Pode-se programar um DSP para processar


dados usando uma das várias estratégias para lidar com o "evento", a chegada dos
dados. Um bit de status ou um sinalizador pode ser lido periodicamente para
determinar se novos dados estão disponíveis. Mas "polling" desperdiça ciclos do
processador. Os dados podem chegar logo após a última pesquisa, mas não podem ser
divulgados até a próxima pesquisa. Isso dificulta o desenvolvimento de sistemas em
tempo real.

A segunda estratégia é que os dados sejam interromper o processador na


chegada. Usar interrupções para notificar o processador é eficiente, embora não seja
tão fácil de programar; ciclos de clock podem ser desperdiçados durante a espera por
uma interrupção. No entanto, a programação de interrupções orientada a eventos está
bem adaptada ao processamento de sinais do mundo real prontamente, a maioria dos
DSPs são projetados para lidar eficientemente com eles. Na verdade, eles são
projetados para responder muito rapidamente a interrupções. O tempo de resposta do
ADSP-2181 para uma interrupção é de cerca de três ciclos de processador; ou seja,
dentro de 75 ns o DSP parou de fazer o que estava fazendo e está lidando com o
evento de interrupção ( vetor ).

Em muitos sistemas baseados em DSP, as taxas de interrupção, com base na taxa de


amostragem de dados de entrada, geralmente não estão relacionadas de forma alguma
com o clock do DSP. No exemplo FIR visto anteriormente nesta série, o processador é
interrompido em intervalos de 125-µs para receber novos dados.
Interromper o manuseio e interromper vetores: Como o processamento de
interrupção é um elemento tão vital nos sistemas DSP, os processadores normalmente
possuem mecanismos de hardware integrados para lidar com as interrupções de
maneira eficiente. Mecanismos hard-wired são mais eficazes do que o software
sozinho porque as rotinas de serviço de interrupção (ISRs) do DSP podem ter que
atender a todas as seguintes demandas:

 Mudança rápida de contexto - alterna do trabalho em uma tarefa e seus


dados ( um contexto ) para outro contexto sem a perda de tempo e
complicações associadas a programas de gravação para salvar o conteúdo do
registro e as informações de status do chip.
 Manipulação de interrupção aninhada - manipule várias interrupções de
prioridades diferentes "simultaneamente". O DSP manipula uma interrupção
por vez, mas uma interrupção de prioridade mais alta pode ter precedência
sobre o tratamento de uma interrupção de prioridade mais baixa.
 Continue aceitando o status de dados / registros - enquanto o DSP atende a
uma interrupção, os eventos continuam ocorrendo no mundo real e os dados
continuam chegando. Para acompanhar o "mundo real", o DSP deve registrar
esses eventos e aceitar os dados - depois processá-los quando terminar de
atender à interrupção.
Em DSPs de dispositivos analógicos, a comutação rápida de contexto é realizada
usando dois conjuntos de registros de dados. Apenas um conjunto está ativo por vez,
contendo todos os dados em processo durante esse contexto. Ao atender uma
interrupção, o computador pode alternar do conjunto ativo para o alternativo sem
precisar salvar temporariamente os dados na memória. Isso facilita a troca rápida
entre tarefas.

Para lidar com várias interrupções, os DSPs de dispositivos analógicos registram seu
estado para cada um. As informações de estado do processador são mantidas em um
conjunto de "pilhas" de status localizadas no seqüenciador de programas do
DSP. Uma "pilha" consiste em um conjunto de registradores de hardware. As
informações de status atuais são "empurradas" para a pilha quando ocorre um
evento. Este mecanismo de pilha também permite que as interrupções
sejam aninhado ; um com maior prioridade pode interromper um com menor
prioridade.

Dois recursos de hardware, trava de interrupção e E / S automatizada permitem que os


DSPs da Analog Devices fiquem a par do "mundo real" durante o processamento de
uma interrupção. A trava evita que o DSP perca eventos importantes durante a
manutenção de uma interrupção. O outro recurso, compreendendo várias formas de E
/ S automatizada (incluindo portas seriais, DMA, autobuffering, etc.) permite que
dispositivos externos bombeiem dados para a memória do DSP sem exigir
intervenção do DSP. Portanto, nenhum dado é perdido enquanto o DSP está
"ocupado".

Quando uma solicitação de interrupção é gerada, por uma fonte externa ou por um
recurso interno, o processador DSP armazena automaticamente seu estado atual de
operação e se prepara para executar a rotina de interrupção. Rotinas de interrupção
são despachadas de uma tabela de vetores de interrupção. Uma tabela de vetores de
interrupção é uma área na Memória de Programa com endereços de instrução
atribuídos a funções específicas de interrupção de DSP. Por exemplo, na tabela abaixo,
uma interrupção de Transmissão (Tx) na porta serial 1 (SPORT1) de um processador
ADSP-2181 fará com que a próxima instrução seja executada na memória de
programa (PM) 0x0020, seguida pelo conteúdo da próximos três locais, através de
0x0023 (o interromper a rotina ). Como os 12 itens na tabela indicam, um
ADSP-2181 pode manipular interrupções de 11 locais (hardware externo, portas
DMA e portas seriais) e a redefinição do processador. A tabela lista as instruções
programadas atribuídas a cada fonte de vetor de interrupção nos locais de memória
0x0000 a 0x002F para um programa de filtro FIR.

Jump start; nop; nop; nop; / * PM (0x0000-03): redefinir vetor * /


rti; nop; nop; nop; / * PM (0x0004-07): vetor IRQ2 * /
rti; nop; nop; nop; / * PM (0x0008-0B): vetor IRQL1 * /
rti; nop; nop; nop; / * PM (0x000C-0F): vetor IRQL0 * /
ar = dm (stat_flag); ar = passar ar; if eq_rti; salte next_cmd;
/ * PM (0x0010-13): vetor Tx SPORT0 * /
jump input_samples; nop; nop; nop;
/ * PM (0x0014-17): vetor SPORT0 Rx * /
irqe salto; nop; nop; nop; / * PM (0x0018-1B): vetor de IRQE * /
rti; nop; nop; nop; / * PM (0x001C-1F): vetor BDMA * /
rti; nop; nop; nop; / * PM (0x0020-23): vetor Tx SPORT1 * /
rti; nop; nop; nop; / * PM (0x0024-27): vetor SPORT1 Rx * /
rti; nop; nop; nop; / * PM (0x0028-2B): vetor de timer * /
rti; nop; nop; nop; / * PM (0x002C-2F): vetor de desligamento *
/

Cada vetor de interrupção possui quatro locais de instrução. Normalmente, essas


instruções farão com que o processador salte para outra área da memória para
processar os dados, conforme mostrado nos vetores de interrupção de Redefinição
(em 0x0000), SPORT0 Rx (0x0014) e IRQE (0x0018). Se houver apenas algumas
etapas - como ler um valor, verificar status ou carregar memória - que podem ser
feitas nos quatro locais de instruções disponíveis, elas serão programadas diretamente,
conforme mostrado no vetor SPORT0 Tx (0x0010-13). Qualquer vetor de interrupção
não utilizado pede retorno da interrupção (rti), com três instruções nop (sem
operação).

As instruções nop servem como espaços reservados para instruções - usado para
garantir que a ação de interrupção correta esteja alinhada com o vetor de interrupção
especificado pelo hardware. A instrução rti no início de cada localização vetorial não
usada é tanto o espaço reservado quanto a válvula de segurança. Se uma interrupção
não utilizada for desmascarada por engano ou ativada inadvertidamente, "rti" causará
um retorno à execução normal.

E / S de dados
Nos sistemas DSP, as interrupções são normalmente geradas pela chegada de dados
ou pelo requisito de fornecer novos dados de saída. Interrupções podem ocorrer com
cada amostra, ou podem ocorrer depois que um quadro de dados foi coletado. As
diferenças influenciam muito como o algoritmo DSP lida com os dados.

Para algoritmos que operam em uma base de amostra por amostra, o software DSP
pode ser necessário para lidar com cada valor de dados de entrada e saída. Cada porta
serial DSP incorpora dois registradores de E / S de dados, receber registrar (Rx) e
um transmite registrar (Tx). Quando uma palavra serial é recebida, a porta
normalmente gera uma interrupção de recebimento. O processador pára o que está
fazendo, começa a executar o código no local do vetor de interrupção, lê o valor de
entrada do registrador Rx em um registrador de dados do processador e opera nesse
valor de dados ou retorna a sua tarefa em segundo plano. Na tabela acima, o
computador salta para um segmento de programa, "input_samples", executa quaisquer
instruções programadas nesse segmento e retorna da interrupção, diretamente ou
através de um retorno ao vetor de interrupção.

Para transmitir dados, a porta serial pode gerar uma interrupção de Transmissão,
indicando que novos dados podem ser gravados no registro SPORT Tx. O DSP pode
então começar a execução de código no vetor de interrupção SPORT Tx e tipicamente
transferir um valor de um registrador de dados para o registro SPORT Tx. Se a
entrada e saída de dados são controladas pelo mesmo relógio de amostragem, apenas
uma interrupção é necessária. Por exemplo, se um segmento de programa for iniciado
por Sincronização de interrupção de recebimento, novos dados serão lidos durante a
rotina de interrupção; então, o resultado previamente computado, que está sendo
mantido em um registrador, seria transmitido, ou um novo resultado seria computado
e imediatamente transmitido - como a etapa final da rotina de interrupção.

Todos esses mecanismos ajudam um DSP a abordar a capacidade de emular o que um


sistema analógico faz naturalmente - processar dados continuamente em tempo real -
mas com precisão e flexibilidade digitais. Além disso, em um sistema digital
eficientemente programado, os ciclos restantes do processador deixados entre os
conjuntos de dados de processamento podem ser usados para lidar com outras
tarefas.

Considerações de programação
Em um sistema "em tempo real", a velocidade de processamento é essencial. Usando
o autobuffering SPORT, nenhum tempo é perdido para os dados de E / S. Em vez
disso, a meta de gerenciamento de dados é garantir que o endereço selecionado aponte
para os novos dados.

No exemplo do filtro FIR ( Diálogo Analógico 31-3, página 15), uma solicitação de
interrupção Receive SPORT é gerada quando o autobuffer de entrada está cheio,
significando que o DSP recebeu três palavras de dados: status, dados do canal
esquerdo e dados do canal direito. Como esse aplicativo simplificado usa dados de
canal único, somente o valor de dados que reside no local rx_buf + 1 é usado pelo
algoritmo.

Expansão do Algoritmo do Filtro Em outras aplicações, o tratamento de dados pode


estar mais envolvido. Por exemplo, se o filtro FIR do exemplo fosse expandido para
uma implementação de dois canais, o código do algoritmo do DSP central não
precisaria ser alterado. O código relacionado ao tratamento de dados, no entanto, teria
que ser modificado para considerar um segundo fluxo de dados e um segundo
conjunto de coeficientes.

No código de filtro, dois novos buffers na memória seriam necessários para manipular
o fluxo de dados adicional e o conjunto adicional de coeficientes. O loop de filtro do
núcleo pode ser isolado como uma função "chamável" separada. Essa técnica permite
que o mesmo código seja usado, independentemente dos valores dos dados de
entrada. Os benefícios deste estilo de programação incluem código legível, algoritmos
reutilizáveis e tamanho de código reduzido. Se uma abordagem modular não for
tomada, o loop de filtro teria que ser repetido, usando espaço de memória DSP
adicional.

A rotina de interrupção Recebimento do SPORT consistiria, então, na configuração


do ponteiro e na chamada do filtro. A rotina de filtro revisada é mostrada na listagem
a seguir:

Filtro: cntr = taps - 1;


mr = 0, mx0 = dm (i2, m1), my0 = pm (i5, m5);
/ * clear accumulator, obtenha os primeiros dados
valor do coeficiente * /
filt_loop até ce; / * loop de zero sobrecarga de configuração * /
filt_loop: mr = sr + mx0 * my0 (ss), mx0 = dm (i2, m1),
my0 = pm (i5, m5); / * MAC e duas buscas de dados * /
mr = mr + mx0 * my0 (rnd); / * final multiplicar, arredondar para 16
bits
resultado * /
se mv sentou mr; / * verifique se há estouro * /
rts; /* Retorna */

É importante observar que as únicas modificações no loop do filtro principal foram a


adição de um rótulo, "Filter:" no início da rotina, e a adição de uma instrução "rts"
(retorno da sub-rotina) no final. Essas adições alteram o código de filtro de uma rotina
autônoma para uma sub-rotina que pode ser chamada de outras rotinas. Não mais uma
rotina de propósito único, tornou-se uma sub-rotina reutilizável e exigível.

Com o filtro de núcleo configurado como uma sub-rotina que pode ser chamada, os
requisitos de manipulação de dados de dois canais agora podem ser endereçados. Para
simplificar alguns dos problemas de programação, este exemplo pressupõe que os
canais esquerdo e direito usam os mesmos coeficientes de filtro.

Na terceira edição desta série, todo o código do assembly do aplicativo de filtro foi
exibido. No topo da listagem de código, todos os buffers de memória necessários
foram declarados. Para expandir o aplicativo de filtro para manipular dois canais de
dados, as novas variáveis e os buffers necessários precisam ser declarados. Para
os dados recebidos, a declaração do buffer,

.var / dm / circ_filt_data [toques]; / * buffer de dados de entrada * /


precisaria ser substituído por dois buffers, declarados como

.var / dm / circ_filt1_data [toques]; / * buffer de dados de entrada do canal esquerdo *


/
.var / dm / circ_filt2_data [toques]; / * buffer de dados de entrada do canal direito * /

Como ambos os canais devem ter os mesmos coeficientes de filtro aplicados a eles, os
buffers de dados são de igual tamanho.

A sub-rotina de loop de filtro espera que certos valores de dados e coeficientes sejam
acessados usando registros de endereços específicos. Especificamente, o
registrador de endereço I2 deve apontar para a amostra de dados mais antiga, e I5
deve apontar para o valor de coeficiente adequado antes da rotina de filtro ser
chamada.

Como os filtros dos canais esquerdo e direito estarão compartilhando os mesmos


ponteiros de memória, deve haver um mecanismo para diferenciar os dois fluxos de
dados. Para o ponteiro de dados, I 2 , duas novas variáveis precisam ser definidas,
"filter1_ptr" e "filter2_ptr."

Esses locais na memória serão usados para armazenar os valores de endereço


apropriados para cada fluxo de dados. A capacidade de buffer circular do ADSP-2181
é usada para garantir que o ponteiro de dados esteja sempre no local correto no buffer
sempre que o filtro for executado. Como a sub-rotina agora está lidando com dois
buffers, os locais do ponteiro precisam ser salvos quando o processamento de cada
canal for concluído.

Para configurar os ponteiros, duas variáveis na memória de dados precisam ser


declaradas da seguinte maneira:

.var / dm filter1_ptr; / * apontador de dados para dados do canal esquerdo * /


.var / dm filter2_ptr; / * apontador de dados para dados do canal direito * /

Essas variáveis precisam ser inicializadas com o endereço inicial de cada um


dos buffers de dados;

.init filter1_ptr: ^ filt1_data; / * inicializar o ponto de partida


canal esquerdo * /
.init filter2_ptr: ^ filt2_data; / * inicializar o ponto de partida
canal direito * /

O software montador DSP reconhece o símbolo "^" para significar "endereço de". O
software vinculador DSP preenche o valor de endereço apropriado. Desta forma, as
variáveis de ponteiro no programa executável são inicializadas com os endereços
iniciais dos buffers de memória apropriados.

A listagem a seguir mostra como a rotina de interrupção do filtro FIR usa esses novos
elementos de memória. A sub-rotina original do filtro da 3ª parcela foi modificada
para fornecer dois canais separados de filtragem. Em vez de iniciar diretamente no
cálculo do filtro, a rotina deve primeiro carregar o ponteiro de dados apropriado. A
rotina de filtro é então chamada e a saída resultante é colocada no local correto para
transmissão.

/ * -------------------- Filtro FIR -------------------- * /


input_samples:
ena sec_reg; / * use banco de registradores de sombra * /

/ * configurado para filtro 1 * /


i2 = dm (filter1_ptr); / * set data pointer para o filtro 1 * /
ax0 = dm (rx_buf + 1); / * ler dados do canal esquerdo * /
dm (i2, m1) = ax0; / * escreve novos dados na linha de atraso,
ponteiro apontando agora para dados mais antigos * /

filtro de chamada; / * executar o primeiro filtro para a esquerda


dados do canal * /

dm (tx_buf + 1) = mr1; / * escreve dados de saída do canal


esquerdo * /
dm (filter1_ptr) = i2; / * salvar ponteiro de dados filter1 atualizado *
/

/ * configurado para filtro 2 * /


i2 = dm (filter2_ptr); / * set data pointer para o filtro 2 * /
ax0 = dm (rx_buf + 2); / * ler dados do canal direito * /
dm (i2, m1) = ax0; / * escreve novos dados na linha de atraso,
ponteiro apontando agora para dados mais antigos * /

filtro de chamada; / * execute o filtro novamente para o


dados do canal direito * /

dm (tx_buf + 2) = mr1; / * gravar dados de saída do canal direito * /


dm (filter2_ptr) = i2; / * salvar ponteiro de dados filter2 atualizado *
/

rti; / * retornar da interrupção * /

Como o algoritmo de filtro principal não lida mais com E / S de dados, esta sub-rotina
pode ser expandida para mais canais de filtragem simplesmente adicionando mais
variáveis de ponteiro e declarando mais espaço de buffer (contanto que exista
memória suficiente!) Da mesma forma, diferentes coeficientes podem ser usados para
os dois filtros configurando variáveis que contêm informações de ponteiro de
buffer de coeficiente. Em ambos os casos, o algoritmo de filtro não precisa ser
alterado. Usando esse estilo de programação modular, o usuário pode criar uma
biblioteca de funções DSP que podem ser chamadas. Diferenças para sistemas
específicos podem, portanto, ser reduzidas a problemas de manipulação de dados, em
vez do desenvolvimento de novos algoritmos. Embora esse estilo de programação não
permita necessariamente que o algoritmo execute sua tarefa mais rapidamente, o
projetista do sistema tem mais flexibilidade em estabelecer como os dados fluem pelo
sistema.

Problemas de interface em tempo real: Até agora, examinamos como a


programação em tempo real em sistemas embarcados depende de resposta rápida a
interrupções, manipulação eficiente de dados e execução rápida de programas. Além
disso, o fluxo de dados para dentro e para fora do processador também influencia
como o sistema funcionará em um ambiente incorporado em tempo real.

Os dados primários que entram e saem de um processador de sinal digital podem ser
paralelos e seriais. Transferências paralelas são tipicamente, pelo menos, tão ampla
como a palavra de dados nativa da arquitectura do processador (16 bits para um
processador da família ADSP-2100, 32 bits para o SHARC ®). Transferências
paralelas ocorrem via barramento de memória externa ou barramento de interface de
host externo do processador. Transferências de dados de série requerem
consideravelmente menos interconexões; eles são freqüentemente usados para se
comunicar com conversores de dados.

Interface serial : A facilidade de interface de hardware é um elemento importante da


implementação eficiente do sistema DSP. O sistema ADSP-2181 EZ-Kit Lite usa um
codec serial AD1847 (COder / DECoder). Os codecs de série permitem transferências
de dados através de uma porta serial (SPORT) no DSP. Esta porta serial não é uma
porta serial assíncrona RS-232 estilo PC; é uma interface síncrona de 5 fios que
transmite sinais de bit-clock, Receive-data, Transmit-data e
frame-synchronization. Os principais benefícios das interfaces seriais são a baixa
contagem de pinos e a facilidade de conexão de hardware. O AD1847 requer apenas 4
sinais para fazer interface com o DSP: relógio serial, receber dados, transmitir dados e
receber sinal de sincronização de quadros. O fluxo de dados seriais é multiplexado por
divisão de tempo (TDM), o que significa que a mesma linha física pode transportar
mais de um tipo de informação em ordem serial. No caso do aplicativo AD1847 no
EZ-Kit Lite, iniciado na última edição, a linha serial transporta as informações de
áudio do canal esquerdo e direito, junto com o controle do codec e as informações de
status.

Como observado anteriormente, o processador tem vários meios para manipular esses
dados. SPORT As interrupções são geradas automaticamente pelo hardware da porta
serial para receber ou transmitir dados e para uma única palavra ou um bloco de
palavras (Figura 2). Interface serial entre o processador de sinal digital e o dispositivo
de E / S
Figura 2. Interface serial entre o
processador de sinal digital e o dispositivo de E / S.

Interface Paralela : Mesmo com um clock de bit serial rodando tão rápido quanto o
processador DSP, uma interface serial troca velocidade de transferência de dados pela
simplicidade da fiação, transferindo uma palavra de dados a uma fração da velocidade
do processador DSP. Para o desempenho do sistema que requer taxas de dados mais
altas, uma interface paralela pode ser usada. Ao fazer a interface em paralelo, o DSP
exerce seus dados externos e endereça os barramentos para ler ou gravar dados em um
dispositivo periférico. No ADSP-2181, os barramentos podem interagir com até 16
bits de dados.

A transferência paralela de dados é sempre mais rápida que as transferências em


série. O DSP pode executar um acesso externo a cada ciclo do processador, mas isso
requer periféricos paralelos realmente rápidos que podem acompanhar, como os chips
rápidos da SRAM. Transferências paralelas de dados com outras entidades geralmente
ocorrem em menos de um por ciclo do processador.

O manuseio de interrupção é diferente para as interfaces serial e paralela. Como o


barramento de dados externo do processador DSP é uma entidade de propósito geral
que manipula todos os tipos de dados, ele não possui linhas de sinal dedicadas para
geração e controle de interrupções; no entanto, outros recursos do DSP estão
disponíveis. No ADSP-2181, várias linhas externas de interrupção de hardware, como
a de seleção de memória de E / S, estão disponíveis para acionamento por um
dispositivo externo, como um conversor A / D ou codec. Essa interface é mostrada na
Figura 3, envolvendo um dispositivo paralelo e o ADSP-2181 DSP. Interface de E / S
paralela para um DSP

Figura 3. Interface de E / S
paralela para um DSP.

Ao responder à interrupção de dados paralelos, o processador lê a fonte apropriada e


geralmente coloca esse valor de dados na memória, executando instruções
semelhantes às mostradas aqui:
irq2_svc: ax0 = IO (ad_converter); dm (i2, m1) = ax0; rti;
"ad_converter" é um endereço definido anteriormente no espaço de E
/ S.

REVISÃO E VISUALIZAÇÃO
O objetivo deste artigo foi detalhar as preocupações de programação que os
desenvolvedores de DSP enfrentam ao manipular E / S e outros eventos em sistemas
em tempo real. Os problemas introduzidos incluem dados em tempo real (amostras e
quadros), interrupções e manuseio de interrupções, E / S automatizada e rotinas de
generalização para criar sub-rotinas que podem ser chamadas. Este breve artigo não
poderia fazer justiça aos muitos níveis de detalhes associados a cada um desses
tópicos. Mais informações estão disponíveis nas referências abaixo. Os tópicos
futuros desta série continuarão sendo desenvolvidos neste aplicativo. O próximo
artigo adicionará mais recursos ao nosso programa de exemplo crescente e descreverá
as técnicas de validação de software (ou seja, depuração).

You might also like