EA075 Projeto de uma Câmera Digital
Faculdade de Engenharia Elétrica e de Computação (FEEC)
Universidade Estadual de Campinas (UNICAMP)
Prof. Levy Boccato
1
2
Introdução Objetivo: explorar todos os conhecimentos
adquiridos sobre processadores, memórias e interfaces para o projeto de uma câmera digital.
Escolhas importantes (e.g., entre processador de propósito geral e processador dedicado) serão avaliadas junto com os respectivos trade-offs.
3
Introdução Câmera digital simples:
Faz a captura de imagens e seu armazenamento em formato digital.
Grandes quantidades de imagens podem ser armazenadas na câmera:
O número de fotos depende da quantidade de memória disponível e do número de bits exigido por cada imagem.
Permite a transferência das imagens para um computador.
4
Introdução Câmera digital simples:
Possibilidades mais recentes:
Uso de múltiplos processadores e memórias em um único CI: systems-on-a-chip.
Explorar a grande capacidade das memórias flash.
Muitas outras funções estão disponíveis em uma câmera atual:
Definição do tamanho de imagem;
Eliminação de fotos;
Aproximação (zoom) ou afastamento da imagem.
5
Introdução Perspectiva do projetista:
Processamento de imagens e armazenamento na memória.
Quando a câmera é acionada, uma imagem é capturada, convertida para o formato digital através de um charge-coupled device (CCD), comprimida e armazenada na memória interna.
Transferência das imagens para o PC.
A câmera digital é conectada ao PC e um programa especial comanda a transferência de imagens.
6
Câmera Digital Charge-Coupled Device (CCD):
Dispositivo de silício formado por muitas células sensíveis à luz.
7
Câmera Digital Ajuste de zero:
Erros de manufatura fazem com que cada célula armazene valores de tensão um pouco maiores (ou menores) que a intensidade real de luz.
Tipicamente, os erros são os mesmos aos longo das colunas, porém diferem de uma linha para outra.
Como corrigir este erro?
Algumas colunas são cobertas com tinta preta para que sempre armazenem um valor correspondente ao caso em que não há luz incidente.
Qualquer leitura diferente de zero nas células cobertas fornece uma noção do desvio em relação ao ponto-zero.
O valor de tensão de cada célula em cada linha é, então, corrigido por meio da subtração do desvio médio encontrado nas células cobertas presentes naquela linha.
8
Câmera Digital Ajuste de zero:
123 157 142 127 131 102 99 235
134 135 157 112 109 106 108 136
135 144 159 108 112 118 109 126
176 183 161 111 186 130 132 133
137 149 154 126 185 146 131 132
121 130 127 146 205 150 130 126
117 151 160 181 250 161 134 125
168 170 171 178 183 179 112 124
136 170 155 140 144 115 112 248 12 14
145 146 168 123 120 117 119 147 12 10
144 153 168 117 121 127 118 135 9 9
176 183 161 111 186 130 132 133 0 0
144 156 161 133 192 153 138 139 7 7
122 131 128 147 206 151 131 127 2 0
121 155 164 185 254 165 138 129 4 4
173 175 176 183 188 184 117 129 5 5
Valores armazenados antes do ajuste de zero Após o ajuste de zero
13
11
9
0
7
2
4
5
Células cobertas
Desvio médio
9
Câmera Digital Compressão:
Visa reduzir a quantidade de bits necessária para o armazenamento de uma imagem, sem, contudo, levar a uma perda significativa de qualidade.
Formato JPEG (Joint Photographic Experts Group) é o padrão utilizado para a representação de imagens digitais comprimidas.
Vamos considerar uma abordagem de compressão baseada na transformada discreta de cosseno (DCT).
10
Câmera Digital Processo de compressão considerado:
Dados da imagem são divididos em blocos de 8 x 8 pixels.
Para cada bloco, são executadas três operações:
DCT;
Quantização;
Codificação de Huffman.
11
Câmera Digital 1º passo: DCT
Seja Dxy o pixel original situado na linha x e coluna y. O valor do pixel transformado, situado na linha u e coluna v, é dado pela relação:
Transformada inversa:
,)16/)12(cos()16/)12(cos()()(4/1),(7,...,0 7,...,0
x y
xy vyuxDvCuCvuF
0,
2
1
0,1
)(h
h
hC
7,...,0 7,...,0
)16/)12(cos()16/)12(cos()()(4/1),(u v
uv yvxuEvCuCyxf
12
Câmera Digital 1º passo: DCT
O novo bloco 8 x 8 obtido após a aplicação da DCT possui algumas propriedades interessantes:
Valores do segundo quadrante representam a “essência” da imagem, ou indicam as linhas gerais da imagem.
Valores do quarto quadrante representam os detalhes da imagem.
É possível reduzir a precisão destes valores e manter uma imagem de qualidade aceitável.
13
Câmera Digital 2º passo: Quantização
Redução da qualidade da imagem visando alcançar uma alta taxa de compressão.
Estratégia: utilizar um número menor de bits para a codificação.
Uma possibilidade seria dividir todos os valores por alguma potência de 2 – uma operação de deslocamento simples para a direita realiza a divisão.
1150 39 -43 -10 26 -83 11 41
-81 -3 115 -73 -6 -2 22 -5
14 -11 1 -42 26 -3 17 -38
2 -61 -13 -12 36 -23 -18 5
44 13 37 -4 10 -21 7 -8
36 -11 -9 -4 20 -28 -21 14
-19 -7 21 -6 3 3 12 -21
-5 -13 -11 -17 -4 -1 7 -4
144 5 -5 -1 3 -10 1 5
-10 0 14 -9 -1 0 3 -1
2 -1 0 -5 3 0 2 -5
0 -8 -2 -2 5 -3 -2 1
6 2 5 -1 1 -3 1 -1
5 -1 -1 -1 3 -4 -3 2
-2 -1 3 -1 0 0 2 -3
-1 -2 -1 -2 -1 0 1 -1
Bloco transformado via DCT Após quantização
Divisão de cada célula por 8
14
Câmera Digital 3º passo: Codificação de Huffman
Primeiramente, cada bloco de 8 x 8 pixels é convertido em uma cadeia ou sequência por meio de um padrão “zigzag”.
Qual cadeia binária deve representar cada valor? A estratégia usada na codificação de Huffman para atingir
compressão consiste em representar os valores que aparecem com maior frequência com um número reduzido de bits, enquanto códigos maiores são usados para representar valores pouco frequentes.
15
Câmera Digital 3º passo: Codificação de Huffman
Árvore de Huffman:
Todos os valores são ordenados segundo a frequência de ocorrência.
Os dois valores de menor frequência dão origem a duas folhas, cujos valores são as próprias frequências.
Estas folhas são combinadas e geram um nó pai cujo valor interno corresponde à soma das frequências dos nós filhos.
Este novo nó é colocado na lista ordenada de frequência no lugar dos nós filhos e o processo de criação de nós na árvore prossegue.
16
Câmera Digital 3º passo: Árvore de Huffman
Árvore de Huffman
(1)
(2)
• Mantemos sempre uma lista dos caracteres, ordenada de forma crescente em termos da frequência de ocorrência. • Juntamos os dois nós (folhas) que formem um novo nó com soma mínima.
17
Câmera Digital 3º passo: Árvore de Huffman
Árvore de Huffman
(3)
(4)
18
Câmera Digital 3º passo: Árvore de Huffman
Árvore de Huffman
(5)
19
Câmera Digital 3º passo: Árvore de Huffman
Árvore de Huffman
Configuração final da árvore de Huffman
20
Câmera Digital 3º passo: Codificação de Huffman
O percurso na árvore da raiz (topo) para a folha define o código binário corresponde ao valor daquele pixel.
Ao tomar o caminho da esquerda, aquele bit é considerado igual a 0.
Ao tomar o caminho da direita, aquele bit é considerado igual a 1.
Propriedade: nenhum código é prefixo de outro código – codificação reversível.
21
Câmera Digital Armazenamento de imagens
Possibilidade:
Seja N o número máximo de imagens que podem ser gravadas.
Reserva-se uma parte da memória para guardar N endereços e N variáveis de tamanho de imagem.
N endereços
e N tamanhos
de imagens 1ª imagem
2ª imagem
N x 4 bytes
Endereço inicial da 2ª imagem: N x 4 + (tamanho da 1ª imagem comprimida)
Tamanho da memória depende de N, do tamanho de cada imagem e da taxa
de compressão.
22
Câmera Digital Transferência de imagens para o PC
Quando a câmera está conectada ao PC e um comando de transferência é recebido:
Leitura das imagens na memória.
Transmissão serial através de uma UART.
Enquanto ocorre a transmissão, os apontadores e as variáveis de tamanho de imagem são zeradas, além de o apontador da memória global receber o endereço inicial (N x 4).
23
Especificação dos Requisitos Requisitos do sistema
Requisitos funcionais: ligados ao comportamento do sistema.
Ex.: A saída X deve ser igual a Y x 2.
Requisitos não-funcionais: restrições quanto às métricas de projeto.
Ex.: A consumo de potência deve ser inferior a 0,001 W.
Especificações iniciais fornecidas por um departamento de marketing podem ser muito gerais, na forma de um documento detalhando a necessidade do mercado por uma câmera digital de baixo custo que: Capture e armazene até 50 imagens de baixa resolução e que permita a
transferência dessas imagens para um computador.
Tenha a máxima duração de bateria possível, custando em torno de 100 dólares.
24
Especificação dos Requisitos Requisitos não-funcionais
Métricas de projeto baseadas nas especificações iniciais.
Desempenho: tempo necessário para processar uma imagem.
Tamanho: número de portas lógicas elementares presentes no CI.
Potência:
Valor médio tem a ver com o consumo de energia ao longo do tempo.
Valor instantâneo afeta a temperatura do sistema.
Energia: envolve o tempo de vida da bateria.
25
Especificação dos Requisitos Requisitos não-funcionais
Classificação:
Restrições: valores devem ser menores (ou, em alguns casos,
maiores) do que certos limiares.
Métricas de otimização: projeto deve tentar obter um produto com o melhor valor possível para esta métrica respeitadas as demais condições da especificação.
Um requisito pode ser tanto uma métrica de otimização quanto uma restrição.
26
Especificação dos Requisitos Requisitos não-funcionais
Desempenho: O processamento de uma imagem deve ser suficientemente rápido – restrição
razoável poderia ser de 1 segundo.
Atrasos podem ser inoportunos; em contrapartida, rapidez é uma característica secundária considerando um mercado de baixo custo.
Conclusão: trata-se de uma métrica de restrição.
Tamanho: Deve-se utilizar um CI que resulte em uma câmera de tamanho razoável.
É uma métrica de restrição e otimização: no máximo, deve ter 200.000 portas lógicas, porém, ocupando o menor tamanho possível.
Potência: Deve operar abaixo de certas temperaturas (não é possível adicionar um
ventilador para resfriamento).
Conclusão: é uma métrica de restrição.
Energia: Trata-se de uma métrica de otimização, pois visamos alcançar a máxima
duração da bateria.
27
Especificação Funcional Informal Um fluxograma é útil para decompor a
funcionalidade em funções mais simples.
saída serial e.g., 011010...
sim não
CCD Entrada
Ajuste de zero
DCT
Quantização
Armazenamento em memória
Mais blocos 8×8 ?
Transmitir serialmente
sim
não Feito?
A câmera projetada trabalhará com imagens de baixa qualidade com resolução de 64 x 64 pixels. O mapeamento de cada função em uma implementação baseada num tipo específico de processador será discutido em breve.
28
Detalhamento de especificações funcionais Agora, as especificações informais são detalhadas em funções que
efetivamente podem ser executadas.
Pode-se utilizar código em C/C++ para descrever cada função – dá origem à 1ª implementação do sistema.
Esta etapa permite um melhor entendimento das operações do sistema.
É possível traçar o perfil do sistema para identificar as funções mais custosas do ponto de vista computacional. É possível obter valores de saída que podem ser utilizados para testar a implementação final.
Arquivo de imagem
101011010110101010010101101...
CCD.C
CNTRL.C
UART.C
Arquivo de saída
1010101010101010101010101010...
CODEC.C CCDPP.C
Modelo executável de uma câmera digital
29
Módulos CCD
Simula o funcionamento do CCD fazendo a leitura de uma imagem a partir de um arquivo.
Três procedimentos:
CcdInitialize: recebe o nome do arquivo em que está a imagem.
CcdCapture: lê a imagem a partir do arquivo, armazenando-a em uma matriz.
CcdPopPixel: fornece um pixel de cada vez da imagem.
30
Módulos CCD
char CcdPopPixel(void) {
char pixel;
pixel = buffer[rowIndex][colIndex];
if( ++colIndex == SZ_COL ) {
colIndex = 0;
if( ++rowIndex == SZ_ROW ) {
colIndex = -1;
rowIndex = -1;
}
}
return pixel;
}
#include <stdio.h>
#define SZ_ROW 64
#define SZ_COL (64 + 2)
static FILE *imageFileHandle;
static char buffer[SZ_ROW][SZ_COL];
static unsigned rowIndex, colIndex;
void CcdInitialize(const char *imageFileName) {
imageFileHandle = fopen(imageFileName, "r");
rowIndex = -1;
colIndex = -1;
}
void CcdCapture(void) {
int pixel;
rewind(imageFileHandle);
for(rowIndex=0; rowIndex<SZ_ROW; rowIndex++) {
for(colIndex=0; colIndex<SZ_COL; colIndex++) {
if( fscanf(imageFileHandle, "%i", &pixel) == 1
) {
buffer[rowIndex][colIndex] = (char)pixel;
}
}
}
rowIndex = 0;
colIndex = 0;
}
31
Módulos CCDPP
Pré-processamento: faz o ajuste do ponto-zero após a leitura de cada linha.
Utiliza os procedimentos CcdCapture e CcdPopPixel para obter a imagem.
#define SZ_ROW 64
#define SZ_COL 64
static char buffer[SZ_ROW][SZ_COL];
static unsigned rowIndex, colIndex;
void CcdppInitialize() {
rowIndex = -1;
colIndex = -1;}
void CcdppCapture(void) {
char bias;
CcdCapture();
for(rowIndex=0; rowIndex<SZ_ROW; rowIndex++) {
for(colIndex=0; colIndex<SZ_COL; colIndex++) {
buffer[rowIndex][colIndex] = CcdPopPixel();
}
bias = (CcdPopPixel() + CcdPopPixel()) / 2;
for(colIndex=0; colIndex<SZ_COL; colIndex++) {
buffer[rowIndex][colIndex] -= bias;
}}
rowIndex = 0;
colIndex = 0;}
char CcdppPopPixel(void) {
char pixel;
pixel = buffer[rowIndex][colIndex];
if( ++colIndex == SZ_COL ) {
colIndex = 0;
if( ++rowIndex == SZ_ROW ) {
colIndex = -1;
rowIndex = -1;
} }
return pixel;}
Exporta os mesmo conjunto de procedimentos que o CCD, com a diferença que a imagem já passou pela etapa de ajuste do zero.
32
Módulos UART
É preciso implementar apenas a transmissão, já que a câmera não recebe dados de entrada do PC.
Procedimentos: UartInitialize: recebe o nome do arquivo a ser transmitido.
UartSend: transmite (neste caso, escreve no arquivo de saída) um byte de cada vez.
#include <stdio.h>
static FILE *outputFileHandle;
void UartInitialize(const char *outputFileName) {
outputFileHandle = fopen(outputFileName, "w");
}
void UartSend(char d) {
fprintf(outputFileHandle, "%i\n", (int)d);
}
33
Módulos CODEC
• Modela a codificação via DCT. • ibuffer contém o bloco 8 x 8 original. • obuffer contém o bloco 8 x 8 codificado. • CodecPushPixel é chamado 64 vezes para preencher o ibuffer com o bloco original. • CodecPopPixel é chamado 64 vezes para passar o bloco codificado armazenado em obuffer. • CodecDoFdct é chamado uma vez para transformar os blocos 8 x 8.
static short ibuffer[8][8], obuffer[8][8], idx;
void CodecInitialize(void) { idx = 0; }
void CodecDoFdct(void) {
int x, y;
for(x=0; x<8; x++) {
for(y=0; y<8; y++)
obuffer[x][y] = FDCT(x, y, ibuffer);} idx = 0;}
void CodecPushPixel(short p) {
if( idx == 64 ) idx = 0;
ibuffer[idx / 8][idx % 8] = p; idx++;}
short CodecPopPixel(void) {
short p;
if( idx == 64 ) idx = 0;
p = obuffer[idx / 8][idx % 8]; idx++; return p;}
34
Módulos CODEC
Ao todo, teremos 64 possíveis valores da função cosseno.
Para melhorar o desempenho, estes valores são pré-computados e armazenados em uma tabela.
Em vez usar a representação de ponto flutuante, os valores foram convertidos em números inteiros através da multiplicação por 32768 e arredondamento para o inteiro mais próximo.
Este valor foi escolhido para que os números possam ser representados por 16 bits (2 bytes).
static const short COS_TABLE[8][8] = {
{32768, 32138, 30273, 27245, 23170, 18204, 12539, 6392},
{32768, 27245, 12539, -6392, -23170, -32138, -30273, -18204},
{32768, 18204,-12539,-32138, -23170, 6392, 30273, 27245},
{32768, 6392,-30273,-18204, 23170, 27245, -12539, -32138},
{32768, -6392,-30273, 18204, 23170, -27245, -12539, 32138},
{32768,-18204,-12539, 32138, -23170, -6392, 30273, -27245},
{32768,-27245, 12539, 6392, -23170, 32138, -30273, 18204},
{32768,-32138, 30273,-27245, 23170, -18204, 12539, -6392}};
static int FDCT(int u, int v, short img[8][8]) {
double s[8], r = 0; int x;
for(x=0; x<8; x++) {
s[x] = img[x][0] * COS(0, v) + img[x][1] * COS(1, v) +
img[x][2] * COS(2, v) + img[x][3] * COS(3, v) +
img[x][4] * COS(4, v) + img[x][5] * COS(5, v) +
img[x][6] * COS(6, v) + img[x][7] * COS(7, v);}
for(x=0; x<8; x++) r += s[x] * COS(x, u);
return (short)(r * .25 * C(u) * C(v));}
static short ONE_OVER_SQRT_TWO = 23170;
static double COS(int xy, int uv) {
return COS_TABLE[xy][uv] / 32768.0;
}
static double C(int h) {
return h ? 1.0 : ONE_OVER_SQRT_TWO /
32768.0;
}
35
Módulos CNTRL
Representa o núcleo do sistema.
CntrlInitialize: apenas para manter consistência com os demais módulos.
CntrlCaptureImage: utiliza o módulo CCDPP para a entrada da imagem e seu armazenamento no buffer.
CntrlCompressImage: decompõe o buffer de tamanho 64 x 64 em blocos 8 x 8 e aplica a DCT em cada bloco utilizando o módulo CODEC. Em seguida, faz a quantização de cada bloco.
CntrlSendImage: transmite a imagem codificada utilizando o módulo UART.
36
Módulos CNTRL
void CntrlSendImage(void) {
for(i=0; i<SZ_ROW; i++)
for(j=0; j<SZ_COL; j++) {
temp = buffer[i][j];
UartSend(((char*)&temp)[0]); /*send upper byte*/
UartSend(((char*)&temp)[1]); /*send lower byte*/ } } }
#define SZ_ROW 64
#define SZ_COL 64
#define NUM_ROW_BLOCKS (SZ_ROW / 8)
#define NUM_COL_BLOCKS (SZ_COL / 8)
static short buffer[SZ_ROW][SZ_COL], i, j, k, l,
temp;
void CntrlInitialize(void) {}
void CntrlCaptureImage(void) {
CcdppCapture();
for(i=0; i<SZ_ROW; i++)
for(j=0; j<SZ_COL; j++)
buffer[i][j] = CcdppPopPixel();}
void CntrlCompressImage(void) {
for(i=0; i<NUM_ROW_BLOCKS; i++)
for(j=0; j<NUM_COL_BLOCKS; j++) {
for(k=0; k<8; k++)
for(l=0; l<8; l++)
CodecPushPixel((char)buffer[i * 8 + k][j * 8 + l]);
CodecDoFdct();/* part 1 - FDCT */
for(k=0; k<8; k++)
for(l=0; l<8; l++) {
buffer[i * 8 + k][j * 8 + l] = CodecPopPixel();
/* part 2 - quantization */
buffer[i*8+k][j*8+l] >>= 6; }}}
37
Módulos Interligando todos os módulos, chegamos a uma
implementação completa da câmera digital.
Main inicializa todos os módulos e, em seguida, usa o CNTRL para capturar, comprimir e transmitir uma imagem.
int main(int argc, char *argv[]) {
char *uartOutputFileName = argc > 1 ? argv[1] :
"uart_out.txt";
char *imageFileName = argc > 2 ? argv[2] :
"image.txt";
/* initialize the modules */
UartInitialize(uartOutputFileName);
CcdInitialize(imageFileName);
CcdppInitialize();
CodecInitialize();
CntrlInitialize();
/* simulate functionality */
CntrlCaptureImage();
CntrlCompressImage();
CntrlSendImage();}
Falhas são mais facilmente detectadas e corrigidas neste modelo.
38
Projeto da Câmera Digital Envolve dois aspectos fundamentais:
Arquitetura:
Processadores (dedicados, genéricos);
Memórias e barramentos.
Mapeamento das funções nos componentes da arquitetura:
Múltiplas funções em um único processador.
Uma função distribuída em um ou mais processadores.
39
Projeto da Câmera Digital Implementação: arquitetura + mapeamento.
Ponto de partida: processador de propósito geral de baixo custo conectado a memória flash. Todas as funções são mapeadas em software, que será executado
pelo processador.
Usualmente, esta opção satisfaz os requisitos de consumo de potência, tamanho e restrições quanto ao tempo de chegada ao mercado.
Se o desempenho não é satisfatório, as implementações podem:
Utilizar outro processador (mais rápido);
Utilizar processadores dedicados para funções de desempenho crítico.
Reescrever as especificações funcionais.
40
1ª implementação Processador de baixo custo: microcontrolador Intel 8051.
Custo total de CI, incluindo o custo NRE: $5.
O consumo de potência deve ser bem inferior a 200 mW.
Tempo para o mercado de aproximadamente 3 meses.
Contudo, o processamento de uma imagem por segundo não é possível:
12 MHz, 12 ciclos por instrução (1 μs)
Execução de 1 milhão de instruções por segundo.
CcdppCapture possui loops aninhados resultando em 4096 iterações.
~100 instruções Assembly por laço.
409.000 instruções por imagem.
Metade do tempo de processamento apenas para a leitura da imagem.
41
2ª implementação Função CCDPP implementada em um processador dedicado.
Aumento do desempenho – menos ciclos do microcontrolador.
Aumento do custo NRE e tempo de chegada ao mercado.
Fácil implementação: datapath relativamente simples e poucos estados no controlador.
UART: implementação simples em um processador dedicado.
EEPROM para a memória de programa e RAM para a memória de dados.
8051
UART CCDPP
RAM EEPROM
SOC
42
2ª implementação UART: permanece em estado de espera até ser acionada.
Comunicação mapeada em memória entre o 8051 e todos os processadores dedicados: Os 8 bits menos significativos do endereço são utilizados para o endereçamento da RAM.
Os 8 bits mais significativos do endereço são utilizados para a decodificação dos dispositivos de entrada-saída.
O estado Start inicia a transmissão dos bytes e, em seguida, ocorre a transição para o estado Data.
O estado Data envia os 8 bits serialmente e, em seguida, ocorre a transição para o estado Stop.
O estado Stop transmite um 1 indicando que a transmissão foi completada e, em seguida, ocorre a transição para o estado Idle.
43
2ª implementação CCDPP: implementação, em hardware, das operações de ajuste de
zero.
Buffer interno, B, mapeado em memória para o 8051.
Variáveis R e C indicam a linha e a coluna do buffer.
O estado GetRow transfere uma linha do CCD para B.
66 bytes: 64 pixels + 2 blacked-out pixels.
O estado ComputeBias calcula o desvio para a linha em questão e armazena o resultado na variável Bias.
O estado FixBias percorre a mesma linha, subtraindo Bias de cada elemento.
Estado NextRow: ajusta os índices e avança para o estado GetRow para repetir o processo para a próxima linha; ou, então, avança para o estado Idle quando todas as 64 linhas estão completas.
44
2ª implementação Conectando os componentes do system-on-a-chip (SOC):
Todos os processadores dedicados e a RAM são conectados ao barramento de memória do 8051.
Leitura:
Processador coloca o endereço no barramento de 16 bits.
Sinal de controle é ativado durante um ciclo.
Leitura de dados do barramento de dados (8 bits) no próximo ciclo.
Dispositivo (RAM ou processador dedicado) detecta o sinal de controle de leitura.
Detecção / Decodificação de endereço.
Fornecimento do dado requisitado no barramento de dados durante um ciclo.
45
2ª implementação Conectando os componentes do system-on-a-chip (SOC):
Todos os processadores dedicados e a RAM são conectados ao barramento de memória do 8051.
Escrita:
Processador coloca o endereço no barramento de 16 bits e o dado (8 bits) no barramento de dados.
Sinal de controle de escrita é acionado durante um ciclo de relógio.
Dispositivo (RAM ou processador dedicado) detecta o sinal de controle de escrita.
Detecção / Decodificação de endereço.
Leitura e armazenamento do dado proveniente do barramento de dados.
46
2ª implementação Software:
O modelo detalhado do sistema fornece a maior parte do código (bem como a hierarquia dos módulos, nomes de procedimentos, programa principal).
Código do módulo da UART e do módulo CCDPP devem ser ajustados. Substituição em memória:
Xdata utilizado para ler/armazenar variáveis do barramento externo da memória.
_at_ especifica o endereço da memória para armazenar essas variáveis.
Byte enviado para U_TX_REG pelo processador que invocará a UART.
U_STAT_REG utilizado pela UART para indicar se está pronto para o próximo byte (afinal, a UART pode ser bem mais lenta que o processador).
Modificação semelhante no código do CCDPP.
Todos os outros módulos permanecem inalterados.
static unsigned char xdata U_TX_REG _at_ 65535;
static unsigned char xdata U_STAT_REG _at_ 65534;
void UARTInitialize(void) {}
void UARTSend(unsigned char d) {
while( U_STAT_REG == 1 ) {
/* busy wait */
}
U_TX_REG = d;
}
Código reescrito #include <stdio.h>
static FILE *outputFileHandle;
void UartInitialize(const char *outputFileName) {
outputFileHandle = fopen(outputFileName, "w");
}
void UartSend(char d) {
fprintf(outputFileHandle, "%i\n", (int)d);
}
Código original
47
2ª implementação Todo o SOC é testado em um simulador VHDL.
Interpretação de descrições VHDL e simulação da execução das funções do sistema.
Testes funcionais.
Número de ciclos de relógio para o processamento de uma imagem – desempenho.
A descrição no nível de portas lógicas é obtida com o auxílio de ferramentas de síntese. A ferramenta de síntese parece com um compilador para processadores
dedicados.
Simulação em modelos (portas) para a obtenção de dados para a análise do consumo de potência do sistema (nº de vezes que a porta chaveia de 1 para 0 ou de 0 para 1).
Contagem do número de portas por área no chip.
48
2ª implementação Obtendo as métricas de projeto da implementação:
VHDL simulator
VHDL VHDL VHDL
Execution time
Synthesis tool
gates gates gates
Sum gates
Gate level simulator
Power equation
Chip area
Power
49
2ª implementação Análise:
Tempo total de execução para o processamento de uma imagem: 9,1 segundos.
Consumo de potência: 0,033 W.
Consumo de energia: 0,30 joules (9,1 s x 0,033 W).
Área total do chip: 98.000 portas.
50
3ª implementação O tempo de processamento de 9,1 segundos por imagem está
longe do desejado.
Uma execução da implementação 2 revela que o processador gasta a maior parte dos ciclos de relógio realizando o cálculo da DCT. Logo, a função DCT é uma forte candidata a sofrer modificações.
A opção de desenvolver um hardware customizado para a DCT requer um esforço maior na etapa de desenvolvimento.
Em vez disto, a velocidade da DCT será aprimorada através de modificações no programa.
51
3ª implementação Operações em ponto flutuante (custo):
DCT utiliza ~260 operações em ponto flutuante para cada transformação de pixel.
Como cada imagem é formada por 4096 pixels, são executadas 1 milhão de operações em ponto flutuante por imagem.
O processador Intel 8051 não trabalha com operações em ponto flutuante.
O compilador emula as operações em ponto flutuante, criando rotinas para cada operação (soma, multiplicação) em ponto flutuante.
Cada rotina utiliza dezenas de operações com números inteiros.
Dessa forma, mais de 10 milhões de operações com números inteiros são necessárias para o processamento de uma imagem.
52
3ª implementação Alternativa: Aritmética de ponto fixo
Um número real passa a ser representado por um número inteiro.
A parte fracionária (após o ponto decimal) é representada por um número fixo de dígitos binários – quanto maior o número de bits, maior a precisão desta representação.
Esquema de conversão: Multiplicação do valor real por 2d, onde d é o número de bits da parte fracionária.
Arredondamento para o valor inteiro mais próximo.
Exemplo: representação de 3,14 como um número inteiro de 8 bits com 4 bits para a parte fracionária.
3,14 × 24 = 50,24 ≅ 50 = 0011 0010
0 0 1 0
2-1 2-2 2-3 2-4
0,5 0,25 0,125 0,0625
0 0 1 1
23 22 21 20
,
8 4 2 1 Pesos
53
3ª implementação Operações com representação em ponto fixo
Adição: equivalente à soma de inteiros Exemplo: 3,14 + 2,71 = 5,85
3,14 – representado como 0011 0010 = 50
2,71 – representado como 0010 1011 = 43
50 + 43 = 93 – 0101 1101
A cadeia binária 0101 1101 corresponde a
Multiplicação: equivalente à multiplicação de inteiros com subsequente deslocamento para a direita do resultado segundo o número de bits que compõem a parte fracionária. Exemplo: 3,14 × 2,71 = 8,5094
50 × 43 = 2150 = 1000 0110 0110
Deslocamento para a direita de 4 bits: 1000 0110
812552120212120212120 43210123 ,
37582021212020202021 43210123 ,
54
3ª implementação Implementação do CODEC de ponto fixo
A tabela fornece agora a representação em ponto fixo com 8 bits dos valores da função cosseno.
6 bits são utilizados para a parte fracionária.
O resultado de cada multiplicação é deslocado para a direita por 6 bits.
void CodecDoFdct(void) {
unsigned short x, y;
for(x=0; x<8; x++)
for(y=0; y<8; y++)
outBuffer[x][y] = F(x, y, inBuffer);
idx = 0;
}
static const char code COS_TABLE[8][8] = { { 64, 62, 59, 53, 45, 35, 24, 12 }, { 64, 53, 24, -12, -45, -62, -59, -35 }, { 64, 35, -24, -62, -45, 12, 59, 53 }, { 64, 12, -59, -35, 45, 53, -24, -62 }, { 64, -12, -59, 35, 45, -53, -24, 62 }, { 64, -35, -24, 62, -45, -12, 59, -53 }, { 64, -53, 24, 12, -45, 62, -59, 35 }, { 64, -62, 59, -53, 45, -35, 24, -12 } };
static const char ONE_OVER_SQRT_TWO = 5;
static short xdata inBuffer[8][8], outBuffer[8][8], idx;
void CodecInitialize(void) { idx = 0; }
static unsigned char C(int h) { return h ? 64 : ONE_OVER_SQRT_TWO;}
static int F(int u, int v, short img[8][8]) {
long s[8], r = 0;
unsigned char x, j;
for(x=0; x<8; x++) {
s[x] = 0;
for(j=0; j<8; j++)
s[x] += (img[x][j] * COS_TABLE[j][v] ) >> 6;
}
for(x=0; x<8; x++) r += (s[x] * COS_TABLE[x][u]) >> 6;
return (short)((((r * (((16*C(u)) >> 6) *C(v)) >> 6)) >> 6) >> 6);
}
void CodecPushPixel(short p) {
if( idx == 64 ) idx = 0;
inBuffer[idx / 8][idx % 8] = p << 6; idx++;
}
55
3ª implementação Análise:
Mesma técnica de análise que aquela utilizada na 2ª implementação.
Tempo de processamento de cada imagem: 1,5 segundos.
Consumo de potência: 0,033 W.
Consumo de energia: 0,050 J.
Área total do chip: 90.000 portas (8000 portas a menos que a 2ª implementação) – menos memória é usada para o código.
56
4ª implementação 4 registradores com endereços mapeados em memória:
C_DATAI_REG / C_DATAO_REG: utilizados para entrada / saída de blocos 8 x 8 do CODEC.
C_CMND_REG: utilizado para comandar o funcionamento do CODEC.
Escrita do valor 1 neste registrador dispara o CODEC.
C_STAT_REG: indica que o CODEC terminou um bloco e está pronto para o próximo bloco.
Tradução direta do código em C para VHDL para a implementação em hardware (versão em ponto fixo).
Módulo do CODEC em software é alterado de maneira similar ao que foi feito para a UART na implementação 2.
static unsigned char xdata C_STAT_REG _at_ 65527;
static unsigned char xdata C_CMND_REG _at_ 65528;
static unsigned char xdata C_DATAI_REG _at_ 65529;
static unsigned char xdata C_DATAO_REG _at_ 65530;
void CodecInitialize(void) {}
void CodecPushPixel(short p) { C_DATAO_REG = (char)p; }
short CodecPopPixel(void) {
return ((C_DATAI_REG << 8) | C_DATAI_REG);
}
void CodecDoFdct(void) {
C_CMND_REG = 1;
while( C_STAT_REG == 1 ) { /* busy wait */ }
}
57
4ª implementação Análise:
Tempo de processamento de uma imagem: 0,099 segundos.
Consumo de potência: 0,040 W Houve um aumento em relação às implementações 2 e 3 visto que o SOC
possui outro processador.
Consumo de energia: 0,00040 J O tempo de duração da bateria é doze vezes maior do que aquele referente
à 3ª implementação.
Área total do chip: 128.000 portas
Aumento significativo em relação à implementação anterior.
58
4ª implementação Resumo
3ª implementação
Opção mais barata e que requer menos tempo para sua construção; atinge um desempenho próximo do especificado.
4ª implementação Desempenho excelente e com baixo consumo de energia.
Opção mais cara e que pode levar à perda da janela de mercado.
Se a DCT é desenvolvida pelos próprios projetistas, então o custo NRE pode aumentar bem como o tempo para o mercado.
Se for possível adquirir um módulo pronto que compute a DCT, então o custo do CI pode aumentar.
Qual é a melhor escolha?
Implementação 2 Implementação 3 Implementação 4
Desempenho (seg) 9,1 1,5 0,099
Potência (W) 0,033 0,033 0.040
Tamanho (gates ) 98000 90000 128000
Energia (joule ) 0.30 0.050 0.0040