hardware/software co-design para aplicações de...

220
Hardware/Software co-design para aplicações de processamento de voz Pedro Manuel Fonseca da Mota (ee00022) Pedro Manuel Vieira dos Santos (ee00115)

Upload: others

Post on 15-Sep-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz

Pedro Manuel Fonseca da Mota (ee00022) Pedro Manuel Vieira dos Santos (ee00115)

Page 2: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

1

Este projecto foi desenvolvido no âmbito da cadeira de Projecto, Seminário ou

Trabalho de fim de curso em parceria com a empresa Chipidea.

Pretende-se agradecer a orientação dos responsáveis da Feup, professor João canas

Ferreira e professor Aníbal José Ferreira e da empresa Chipidea, em particular aos Engº

António Pacheco e Engº Vasco Santos, pela sua preciosa colaboração.

Page 3: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

2

1 Sumário..................................................................................................................... 9 2 Introdução............................................................................................................... 10 3 O codec de voz AMR ............................................................................................. 12

3.1 Descrição geral ..........................................................................................................12 3.2 Princípios do codificador de voz AMR .....................................................................14 3.3 Princípios do descodificador de voz AMR................................................................18 3.4 Detector de presença de voz (VAD)..........................................................................19 3.5 Controlo do débito (SCR)..........................................................................................21 3.6 Código C para o codec de voz AMR.........................................................................21

3.6.1 Conteúdos do código C .....................................................................................22 3.6.2 Execução do programa ......................................................................................22 3.6.3 Estrutura do código............................................................................................23 3.6.4 Hierarquia do código .........................................................................................27

4 OpenRISC 1200 RISC/DSP Core .......................................................................... 31 4.1 Descrição do OpenRISC 1200 Core..........................................................................31

4.1.1 CPU/DSP...........................................................................................................32 4.1.1.1 Unidade de Instruções ...................................................................................33 4.1.1.2 Registos para uso genérico (GPR).................................................................33 4.1.1.3 Unidade de Load/Store ..................................................................................34 4.1.1.4 Excepções ......................................................................................................34 4.1.1.5 System Unit ...................................................................................................34 4.1.1.6 Pipeline e MAC Unit .....................................................................................34 4.1.1.7 DSP MAC......................................................................................................35

4.1.2 Caches................................................................................................................35 4.1.3 Memory Management Unit ...............................................................................36 4.1.4 Power Management Unit ...................................................................................36 4.1.5 Unidade de Debug .............................................................................................37 4.1.6 Tick Timer Integrado.........................................................................................37 4.1.7 Programmable Interrupt Controller ...................................................................37 4.1.8 Unidades Adicionais E Definidas Pelo Utilizador ............................................37 4.1.9 Ferramentas De Suporte Ao Desenvolvimento .................................................38 4.1.10 Sistemas Operativos Suportados: ......................................................................38 4.1.11 Interface do Sistema ..........................................................................................38

4.2 Nível de transferência lógica de registos do OR1200 ...............................................38 4.2.1 CPU Core top-level ...........................................................................................41 4.2.2 Slices associadas ao CPU Core .........................................................................44 4.2.3 Top-level do OPENRISC 1200 .........................................................................44 4.2.4 Adaptando o Or1k ao espaço disponível ...........................................................47

4.3 Ferramentas de desenvolvimento ..............................................................................50 4.3.1 Ferramentas disponíveis e funcionalidade.........................................................50 4.3.2 Instalação das ferramentas.................................................................................50 4.3.3 Produção de binários e ferramentas auxiliares ..................................................53 4.3.4 Simulação dos binários produzidos ...................................................................61 4.3.5 Funções de interesse presentes na libraria usada no linking..............................68

5 Profiling e análise do codec AMR.......................................................................... 70 5.1 Introdução..................................................................................................................70

Page 4: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

3

5.2 Análise ao estilo de programação definido pela norma.............................................70 5.2.1 Operações básicas..............................................................................................71

5.3 Uso do ficheiro count.c para realizar o profiling do codec .......................................72 5.4 Profiling do codec AMR ...........................................................................................73 5.5 Optimização do algoritmo – pesquisa do codebook inovativo no modo 12.2 kbit/s.75 5.6 Medição das operações básicas no codec ..................................................................78

6 Pequeno programa a simular no processador – lei A ............................................. 80 6.1 Introdução..................................................................................................................80 6.2 A lei A .......................................................................................................................80 6.3 Implementação da lei A no processador....................................................................81

7 O caminho para a implementação do Or1k em hardware...................................... 83 7.1 Plataforma de desenvolvimento.................................................................................83 7.2 Comunicação entre a memória e o Or1k ...................................................................83 7.3 Controlador de Memórias..........................................................................................84

7.3.1 Área ocupada pelo controlador de memórias ....................................................86 7.3.2 Configuração do controlador de memórias .......................................................87 7.3.3 Aceder aos registos de configuração e ao espaço de memória..........................89 7.3.4 Testbench do controlador de memórias .............................................................91 7.3.5 Descrição das unidades auxiliares para teste.....................................................92

7.3.5.1 Testes pretendidos para o modelo desenvolvido e concretização .................96 7.3.5.2 Formas de onda obtidas e o protocolo wishbone...........................................97

7.4 Or1k e memory controller: necessidade de um arbitrador ......................................102 7.4.1 Testbench para o sistema master/slave............................................................105

8 Adaptação da norma do codec AMR à arquitectura do processador OpenRISC 1200 107

8.1 Definição dos tipos de variáveis no OpenRISC1200 ..............................................107 8.2 Funções não reconhecidas pelo compilador do OpenRISC1200.............................108 8.3 Optimização das operações básicas no OpenRISC1200 .........................................111

8.3.1 Escrita de instruções assembly em código C...................................................111 8.3.2 Colocação das operações básicas inline ..........................................................112 8.3.3 O uso de macros mas operações básicas .........................................................113 8.3.4 Alteração do código nas funções básicas ........................................................115

8.3.4.1 As flags de Overflow e Carry ......................................................................115 8.3.4.2 Instruções de adição/subtracção ..................................................................116 8.3.4.3 Instruções de multiplicação .........................................................................117 8.3.4.4 Instruções de normalização .........................................................................118 8.3.4.5 Instruções shift left/right..............................................................................118 8.3.4.6 Instruções mac .............................................................................................119 8.3.4.7 Outras instruções .........................................................................................121

8.3.5 Problemas encontrados....................................................................................121 8.4 Problemas do compilador ........................................................................................124 8.5 Melhorias observadas pelo uso das macros.............................................................125

9 Perspectivas de desenvolvimento futuras ............................................................. 127 9.1 Operações básicas a serem implementadas na arquitectura do OPENRISC1200 ...127 9.2 32 bits versus 16 bits ...............................................................................................127

10 Conclusões........................................................................................................ 129 11 Bibliografia....................................................................................................... 131

Page 5: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

4

Lista de Figuras Figura 1: Funções gerais do processamento de áudio do codec AMR......................................13 Figura 2: Diagrama de blocos simplificado do modelo de síntese de voz CELP......................14 Figura 3: Diagrama de blocos simplificado do codificador de voz AMR.................................17 Figura 4: Diagrama de blocos simplificado do descodificador de voz AMR. ..........................19 Figura 5: Diagrama de blocos simplificado do algoritmo VAD. ..............................................20 Figura 6: Diagrama de blocos de uma ligação com operação SCR...........................................21 Figura 7 - OpenRISC 1200 Core ...............................................................................................31 Figura 8 - Blocos que constituem o CPU/DSP Core .................................................................33 Figura 9: Estrutura da cache ......................................................................................................36 Figura 10 – CvsGet da página www.opencores.org ..................................................................39 Figura 11: Esquema que representa o Core do CPU .................................................................42 Figura 12: Organização do top-level do Or1k (slices ocupadas por cada módulo)...................45 Figura 13: Configuração do OpenRisc 1200 no seu top-level e interface com o exterior.........49 Figura 14: Resultados obtidos ao ser invocado o or32-uclinux-objdump –S mul.....................58 Figura 15:Resultados obtidos ao ser invocado o or32-uclinux-readelf –a mul .........................60 Figura 16: Resultados da execução do comando or32-uclinux-readelf –x 1 mul .....................60 Figura 17:Resultados obtidos ao ser invocado o or32-uclinux-size -- radix=16 mul ( formatação em hexadecimal).....................................................................................................61 Figura 18: Configuração da memória usada no simulador........................................................65 Figura 19:Resultado da execução do programa de teste mul ....................................................67 Figura 20: Resultado da simulação do ficheiro representado acima .........................................69 Figura 21: Interface necessário para realizar a comunicação com a memória da Cypress .......84 Figura 22: Modelo pretendido em relação ao controlador de memórias...................................85 Figura 23:Arquitectura do controlador de memórias...............................................................86 Figura 24:Registos de configuração presentes no controlador de memórias ............................90 Figura 25:Modelo usado no testbench.......................................................................................92 Figura 26: Modo de geração dos endereços quando se realizam bursts....................................94 Figura 27: Timings e formas de onda associados à leitura da memória da Micron ..................94 Figura 28:Timings e formas de onda que estão associados à memória da Micron ...................95 Figura 29: Programação da mascara para o base address e do control status register ..............96 Figura 30:Configuração do CSC register e TMS register .........................................................96 Figura 31: Resultado da execução do testbench default relativo ao memory controller ...........97 Figura 32: Formas de onda associadas à escrita/leitura usando o protocolo wishbone .............99 Figura 33:Descrição dos sinais de wishbone...........................................................................100 Figura 34: Memória instanciada no sistema............................................................................100 Figura 35: Resultado da simulação em relação aos sinais da SSRAM ...................................101 Figura 36: Modificação para fazer uso da memória da Cypress .............................................102 Figura 37: Forma de ondas obtidas com a memória da Cypress .............................................102 Figura 38 Configuração do Wishbone builder ........................................................................104 Figura 39: Modelo Master Model para teste ...........................................................................105 Figura 40 : Teste do master model com acessos alternados ....................................................106 Figura 41: Resultados da execução do testbench com acesso concorrente dos.......................107

Page 6: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

5

Page 7: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

6

Lista de Tabelas

Tabela 1: Alocação de bits do algoritmo do codec AMR para uma frame de 20 ms. ...............18 Tabela 2: Estruturas existentes no codificador de voz AMR. ...................................................26 Tabela 3: Estruturas existentes no descodificador de voz AMR. ..............................................27 Tabela 4: Estrutura da chamada das funções do codificador.....................................................28 Tabela 5: Estrutura da chamada das funções da função cbsearch. ............................................29 Tabela 6: Estrutura da chamada das funções da função gainQuant. .........................................29 Tabela 7: Estrutura da chamada das funções do descodificador. ..............................................30 Tabela 8: Macros e respectiva interferência no sistema ............................................................40 Tabela 9: Módulos presentes no CPU Core, correspondência com ficheiro e respectiva funcionalidade ...........................................................................................................................43 Tabela 10: Ficheiro e funcionalidade correspondentes para um determinado módulo do Or1k...................................................................................................................................................46 Tabela 11: Slices ocupadas por cada uma das memórias ..........................................................49 Tabela 12:Comandos disponíveis no simulador e respectiva funcionalidade ...........................64 Tabela 13: Secções que constituem o sim.cfg e que podem sofrer alterações ..........................67 Tabela 14: Operações básicas usadas pela norma do codec AMR............................................72 Tabela 15: Peso computacional do codec AMR em WMOPS (weighted million operations per second).......................................................................................................................................74 Tabela 16: Peso computacional do codificador de voz AMR no modo 12.2 kbit/s em WMOPS....................................................................................................................................................75 Tabela 17: Peso computacional do descodificador de voz AMR no modo 12.2 kbit/s em WMOPS. ...................................................................................................................................75 Tabela 18: Posições potenciais dos pulsos individuais no codebook algébrico para o modo 12.2 kbit/s. .........................................................................................................................................76 Tabela 19: Número de ocorrências médias das operações básicas do codec no modo 12.2 kbit/s por frame. ..................................................................................................................................79 Tabela 20: Codificação definida pela lei A. ..............................................................................80 Tabela 21: Configuração do Chip select register para uma memória SSRAM.........................88 Tabela 22: Lista de sinais associados ao protocolo wishbone e respectiva funcionalidade (obtidos a partir do documento de wishbone) ...........................................................................98 Tabela 23: Número de instruções obtido da simulação para o codificador e descodificador .126 Tabela 24: MIPS médio para codificador e descodificador ....................................................126

Page 8: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

7

Ficheiros de Apoio Ficheiro de apoio 1: default.ld- contém as definições das diversas regiões de memória e endereços iniciais.......................................................................................................................55 Ficheiro de apoio 2:Makefile que permite a criação do binário a ser usado para a simulação .56 Ficheiro de apoio 3: Aspecto do simulador. São evidenciados os registos e as instruções do processador. ...............................................................................................................................62 Ficheiro de apoio 4: Ficheiro que mostra a potencialidade das funções referidas ....................69

Page 9: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

8

Anexos

Anexo 1:Versão simplificada do algoritmo do codificador ficheiro s10_8pf.c ......................132 Anexo 2:Contagem das operações básicas da norma do codec – ficheiro count.c..................139 Anexo 3: Implementação da lei A em código C......................................................................145 Anexo 4:Top level do CPU .....................................................................................................152 Anexo 5: Instruções de vírgula fixa do processador Or1k ......................................................153 Anexo 6: Funções básicas da norma do codec implementadas em asssembly........................160 Anexo 7: tt_ssram.v.................................................................................................................169 Anexo 8: bench.v.....................................................................................................................172 Anexo 9: wb.vhd (descrição do master slave).........................................................................179 Anexo 10: Wishone.defines (definições para a elaboração do master slave)..........................183 Anexo 11: Modelo verilog da memória da Cypress ................................................................184 Anexo 12: Modelo verilog da memória da Micron .................................................................191 Anexo 13: bench1.v.................................................................................................................195 Anexo 14: bench2.v.................................................................................................................204 Anexo 15: Or1k TOP level......................................................................................................214 Anexo 16: mc_defines.v ..........................................................................................................215 Anexo 17 : Top level do master slave .....................................................................................219

Page 10: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

9

1 Sumário

A sociedade moderna assenta a sua dinâmica nas telecomunicações e contacto em

tempo real. Por essa razão vários sistemas capazes de realizar a codificação de voz têm sido

desenvolvidos. Integrado no contexto mencionado, neste projecto pretende-se realizar a

implementação de um codificador de voz de débito variável, usando um processador dedicado.

A linha orientadora assenta sobre a optimização quer a nível de software, a que

corresponde a modificação de algoritmos, quer a nível de hardware, onde a arquitectura do

processador é refinada para a aplicação desenvolvida.

Este codec tem a capacidade de baixar ou aumentar o seu débito mediante as maiores

ou menores interferências no canal de comunicação. Nas condições referidas, a codificação de

canal contra erros será maior no caso de interferências mais acentuadas, garantindo-se assim

que o bom desempenho do codec seja mantido.

A arquitectura do processador usado é de domínio público, tendo sido desenhada com

o objectivo de implementar um sistema capaz de ter consumo de potência reduzido,

simplicidade, versatilidade e reduzida área.

A avaliação das vantagens e desvantagens da utilização do modelo open-source no

desenvolvimento de sistemas electrónicos dedicados é um dos motivos nucleares.

Page 11: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

10

2 Introdução

Neste projecto pretendeu-se realizar a implementação da norma 3GPP TS 26.071

V6.0.0 de codificação de audio para UMTS usando o processador OpenRisc 1200.

A arquitectura do processador OpenRISC 1200 é de domínio público, constituindo a

base para as famílias de processadores do tipo RISC/DSP de 32-bit e 64-bit.

Este codec foi escolhido pela Third Generation Partnership Project (3GPP) como o

codec principal para os sistemas da 3ª geração. A filosofia por detrás do AMR é baixar o seu

débito assim que as interferências aumentem, possibilitando desta forma uma maior ou menor

codificação de canal contra erros.

Neste trabalho fez-se o estudo do OR1k, relativamente ao nível de tranferência lógica

de registos, verificando qual era a sua caracterização em termos de performance, velocidade e

área relativamente a um conjunto de módulos que lhe estavam associados. Essa caracterização

é de tal forma importante, que sem a mesma, não se poderia adaptar este processador para a

plataforma de desenvolvimento.

Na parte do codec, fez-se um profiling das funções que ocupam mais processamento e

implementou-se uma modificação no sentido de realizar optimizações a nível computacional

com resultados comprovados.

Numa outra fase, dedicaram-se os esforços para conseguir ter as ferramentas orientadas

a este processador em funcionamento. Fizeram-se testes de pequenos segmentos de código e

com base neles compreendeu-se a forma de poder interagir com o compilador e simulador,

disponíveis de forma livre.

Um teste mais profundo foi a implementação da lei A, onde na parte de software se

fizeram as alterações necessárias à implementação do mesmo na arquitectura deste mesmo

processador. Por outro lado, observou-se como funcionava a memória deste processador,

registos e o assembly gerado com base no código C.

A fase que mais recursos consumiu constitui a adaptação do código desta norma para a

arquitectura do processador, onde diversas modificações tiveram de ser implementadas. Por

outro lado foi necessário integrar o OR1k no sistema oferecido pela plataforma de

desenvolvimento, tendo-se encontrado aí dificuldades.

Page 12: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

11

Após ter sido terminada a adaptação da norma para a arquitectura, procedeu-se à sua

caracterização em termos de instruções executadas no simulador, verificando-se que de facto

uma variedade de optimizações podia ser implementada.

Essas optimizações passaram pela escrita de funções em assembly, revelando-se uma

solução poderosa.

A integração do or1k continua, passando pela introdução de um controlador de

memória, um master/slave capaz de estabelecer prioridades nos barramentos de dados, até

chegar a um modelo final em que o core do OR1k tem acesso à memoria presente na

plataforma de desenvolvimento.

A optimização da norma revelou ser de facto espantosa em termos do número de

instruções agora necessárias, cerca de 2,3 x menos existindo um caminho disponível para

melhorar ainda mais este valor.

No caso de hardware, o teste de um modelo capaz de verificar se o sistema integrado

do or1k, master/slave e memory controller é capaz de funcionar e correr um programa

compilado para este processador, foi a ultima tarefa que se pretendeu cumprir.

Page 13: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

12

3 O codec de voz AMR

3.1 Descrição geral

Desenvolvido pela European Telecommunications Standards Institute (ETSI) e

standardizado para GSM, este codec foi escolhido pela Third Generation Partnership Project

(3GPP) como o codec principal para os sistemas da 3ª geração. A filosofia por detrás do AMR

é baixar o seu débito assim que as interferências aumentem, possibilitando desta forma uma

maior ou menor codificação de canal contra erros. O AMR também é usado para harmonizar

standards entre diferentes sistemas de telecomunicações celulares.

O codec de voz AMR consiste assim num codificador de voz de débitos múltiplos, um

esquema capaz de controlar e gerir os diferentes débitos através dum detector de presença de

voz e um gerador de ruído de conforto, e um mecanismo de cancelamento de erros para

combater os efeitos provocados por erros de transmissão.

Este codec integra oito diferentes débitos desde 4.75 kbit/s a 12.2 kbit/s para codificar

voz propriamente dita e um modo de baixo débito para codificar ruído de fundo. O codificador

de voz é capaz de variar o seu débito a cada frame de 20ms.

Toda a descrição detalhada deste codec pode ser encontrada no site da 3GPP em

http://www.3gpp.org/ftp/Specs/html-info/26-series.htm Aqui podem ser encontrados todos os

documentos que descrevem esta norma em todas as suas vertentes.

Na figura seguinte é possível ver-se aquilo que foi descrito anteriormente. Note-se que

a fonte do sinal a ser codificada tem que surgir no formato PCM de 13 bits. Caso o sinal de

entrada esteja codificado de acordo com a lei A, este terá que ser convertido para PCM de

forma a ser codificado correctamente.

Page 14: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

13

8bit / A-lawto

13-bituniform

LPF A/D

1

2

MS side only

BSS side only GSM 06.60.AMR

GSM 03.50

TRANSMIT SIDE

SpeechEncoder

ComfortNoise

TXFunctions

VoiceActivity

Detector

DTXControl

andOperation

3

6

4

5

6

7

GSM 06.82.AMR GSM 06.81.AMR

GSM 06.60.AMR

GSM 06.62.AMR

SID frame

Speech frame

VAD

13-bituniform

to8bit / A-law

LPFD/A

1

8

MS side only

BSS side only GSM 06.60.AMR

GSM 03.50

RECEIVE SIDE

SpeechDecoder

Speechframe

substitution

DTXControl

andOperation

4

5

9

10

GSM 06.61.AMRGSM 06.81.AMR

GSM 06.60.AMR

GSM 06.62.AMR

SID frame

Speech frame

ComfortNoise

RXFunctions

11

2

SPflag

Info.bits

BFI

Info.bits

SID

TAF

Figura 1: Funções gerais do processamento de áudio do codec AMR.

1) 8-bit A-law or µ-law PCM (ITU-T Recommendation G.711), 8 000 samples/s;

2) 13-bit uniform PCM, 8 000 samples/s;

3) Voice Activity Detector (VAD) flag;

4) Encoded speech frame, 50 frames/s, number of bits/frame depending on the AMR codec mode;

5) SIlence Descriptor (SID) frame;

6) TX_TYPE, 2 bits, indicates whether information bits are available and if they are speech or SID information;

Page 15: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

14

7) Information bits delivered to the 3G AN;

8) Information bits received from the 3G AN;

9) RX_TYPE, the type of frame received quantized into three bits.

3.2 Princípios do codificador de voz AMR

O codec AMR consiste em oito diferentes fontes de débitos: 12.2, 10.2, 7.95, 7.40,

6.70, 5.90, 5.15 e 4.75 kbit/s.

Este codec é baseado no modelo CELP (code-excited linear predictive). É usado um

filtro de síntese obtido por uma análise de 10ª ordem dos parâmetros de predição linear, dados

pela seguinte formúla:

( )( )H z

A z a zii

im= =

+ −=∑

1 1

1 1$ $

onde âi são os parâmetros LP quantizados e m = 10 é a ordem de predição.

A síntese de pitch é feita recorrendo-se ao seguinte filtro:

( )1 1

1B z g zpT=

− −

onde T é o atraso do pitch e gp o seu ganho. Este filtro é implementado usando técnicas

adaptativas.

O modelo de síntese deste codec de voz é ilustrado na figura seguinte:

A(z)1 s(n)^

+

v(n)

c(n)

u(n)

gc

fixedcodebook

adaptive codebook gp

LP synthesis

post-filtering s'(n)^

Figura 2: Diagrama de blocos simplificado do modelo de síntese de voz CELP.

Page 16: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

15

Neste modelo, o sinal de excitação à entrada do filtro de síntese LP é construído

adicionando-se dois vectores de excitação: um do codebook fixo e outro do codebook

adaptativo. O sinal de fala é sintetizado fazendo-se passar pelo filtro LP o sinal proveniente da

soma dos codebooks. O sinal de excitação óptimo é obtido fazendo-se uma análise por síntese

onde o erro entre o sinal original e o sintetizado é minimizado de acordo com uma medida de

distorção pesada perceptual.

O filtro de distorção perceptual usado na técnica de análise por síntese é dado por:

( )( )( )W z

A z

A z=

γ

γ1

2

onde A(z) é o filtro LP não quantizado e 0 < γ2 <γ1 ≤ 1 são os pesos dos factores

perceptuais. Valores de γ1 = 0.9 (para os modos de 12.2 e 10.2 kbit/s) ou γ1 = 0.94 (para os

restantes modos) e γ2 = 0.6 são usados.

O codificador opera com frames de fala de 20 ms cada, correspondendo a 160 amostras

obtidas a um frequência de amostragem de 8000 amostras por segundo. A cada 160 amostras,

o sinal é analisado de forma a extrair os parâmetros do modelo CELP: coeficientes do filtro

LP, índices e ganhos dos codebooks adaptativo e fixo. Estes parâmetros são codificados e

transmitidos. No descodificador, estes parâmetros são descodificados e o sinal de fala é

sintetizado fazendo-se passar o sinal de excitação (codebook adaptativo mais codebook fixo)

pelo filtro de síntese LP.

No diagrama seguinte ilustra-se todas as operações realizadas pelo codificador. Análise

LP é realizada duas vezes por frame para o modo de 12.2 kbit/s e uma vez para os restantes

modos. Para o modo 12.2 kbit/s, dois conjuntos de parâmetros LP são convertidos para line

spectral pairs (LSP) e quantizados juntamente usando split matrix quantization (SMQ) num

total de 38 bits.

Para os outros modos, é feita uma análise LP que é convertida para LSP e quantizada

usando split vector quantization (SVQ). A frame do sinal de fala é dividida em 4 subframes de

5 ms cada (40 amostras). Os parâmetros do codebook fixo e adaptativo são transmitidos em

cada subframe.

Os parâmetros LP quantizados e não quantizados ou suas versões interpoladas são

usadas dependendo da subframe. Um atraso de pitch é estimado em open-loop em cada

Page 17: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz -

Pedro Mota | Pedro Santos

16

subframe (excepto para os modos 5.15 e 4.75 kbit/s onde é feito uma vez por frame) baseado

no sinal de fala perceptualmente pesado.

De seguida as seguintes operações são repetidas para cada subframe:

• O sinal objectivo x(n) é calculado filtrando o sinal residual LP através do filtro de

síntese pesado W(z)H(z) com o estado inicial dos filtros sendo actualizados pela

filtragem do erro entre o LP residual e a excitação (isto é equivalente a subtrair a

resposta do filtro de síntese pesado a uma entrada nula ao sinal de fala pesado).

• A resposta impulsional, h(n) do filtro de síntese pesado é calculada;

• Uma análise, dita closed-loop, do pitch é realizada (para encontrar o atraso e ganho do

pitch), usando o sinal objectivo x(n) e a resposta impulsional h(n), pesquisando em

torno do atraso obtido no open-loop pitch. Pitch fraccionários com 1/6 ou 1/3 de

resolução de uma amostra (dependendo de modo) são usados;

• O sina objectico x(n) é actualizado removendo-se a contribuição do codebook

adaptativo, e este novo sinal objectivo, x2(n), é usado na pesquisa do codebook

algébrico (inovativo), por forma a encontrar o melhor codebook;

• Os ganhos do codebook adaptativo e inovativo são quantificados escalarmente com 4 e

5 bits respectivamente ou quantificados com 6 ou 7 bits (com predição do movimento

da média aplicada ao ganho do codebook fixo);

• Finalmente, as memórias dos filtros são actualizadas (usando o sinal de excitação

determinado) para encontrar o sinal na próxima subframe.

Page 18: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 17

Pedro Mota | Pedro Santos

Figura 3: Diagrama de blocos simplificado do codificador de voz AMR.

A alocação de bits para o codec AMR nos seus diferentes modos é mostrada na

tabela seguinte. Em cada 20 ms de sinal de fala, 95, 103, 118, 134, 148, 159, 204 ou 244

win

dow

ing

and

auto

corr

elat

ion

R[ ]

Levi

nson

-D

urbi

nR

[ ]A(

z)

A(z) LS

Pqu

antiz

atio

n

com

pute

targ

etfo

rin

nova

tion

upda

te fi

lter

mem

orie

s for

next

sub

fram

e

Ope

n-lo

op p

itch

sear

chAd

aptiv

e co

debo

okse

arch

Inno

vativ

e co

debo

okse

arch

Filte

r mem

ory

upda

te

inte

rpol

atio

n

subf

ram

esLS

PA(

z)

LSP

com

pute

wei

ghte

dsp

eech

(4 s

ubfr

ames

)

find

open

-loop

pitc

h

find

best

in

nova

tion

fixed

co

debo

okga

in

quan

tizat

ion

A(z)

^

x(n)

pitc

hin

dex

code

inde

x

fram

esu

bfra

me

s(n)

com

pute

targ

etfo

r ada

ptiv

eco

debo

ok

T ofin

d be

st d

elay

and

gain

x(n) com

pute

impu

lse

resp

onse

A(z)

^A(z)

h(n)

h(n)

A(z)

LPC

ana

lysi

s(tw

ice

per f

ram

e)

A(z)

(twic

e pe

r fra

me)

x (n

)2

quan

tize

LTP-

gain

com

pute

adap

tive

code

book

cont

ribut

ion

LSP

indi

ces

LTP

gain

inde

x

gain

inde

xfix

ed c

odeb

ook

inte

rpol

atio

nfo

r the

4su

bfra

mes

LSP

A(z)

^

for t

he 4

Pre-

proc

essi

ng

Pre-

proc

essin

g

com

pute

exci

tatio

n

Page 19: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 18

Pedro Mota | Pedro Santos

bits são produzidos, correspondendo aos débitos de 4.75, 5.15, 5.90, 6.70, 7.40, 7.95, 10.2

ou 122.2 kbit/s.

Mode Parameter 1st subframe

2nd subframe

3rd subframe

4th subframe total per frame

2 LSP sets 38 12.2 kbit/s Pitch delay 9 6 9 6 30 (GSM EFR) Pitch gain 4 4 4 4 16

Algebraic code 35 35 35 35 140 Codebook gain 5 5 5 5 20 Total 244 LSP set 26

10.2 kbit/s Pitch delay 8 5 8 5 26 Algebraic code 31 31 31 31 124 Gains 7 7 7 7 28 Total 204 LSP sets 27

7.95 kbit/s Pitch delay 8 6 8 6 28 Pitch gain 4 4 4 4 16 Algebraic code 17 17 17 17 68 Codebook gain 5 5 5 5 20 Total 159 LSP set 26

7.40 kbit/s Pitch delay 8 5 8 5 26 (TDMA EFR) Algebraic code 17 17 17 17 68

Gains 7 7 7 7 28 Total 148 LSP set 26

6.70 kbit/s Pitch delay 8 4 8 4 24 (PDC EFR) Algebraic code 14 14 14 14 56

Gains 7 7 7 7 28 Total 134 LSP set 26

5.90 kbit/s Pitch delay 8 4 8 4 24 Algebraic code 11 11 11 11 44 Gains 6 6 6 6 24 Total 118 LSP set 23

5.15 kbit/s Pitch delay 8 4 4 4 20 Algebraic code 9 9 9 9 36 Gains 6 6 6 6 24 Total 103 LSP set 23

4.75 kbit/s Pitch delay 8 4 4 4 20 Algebraic code 9 9 9 9 36 Gains 8 8 16 Total 95

Tabela 1: Alocação de bits do algoritmo do codec AMR para uma frame de 20 ms.

3.3 Princípios do descodificador de voz AMR

No diagrama da figura seguinte é ilustrado o processo de descodificação e síntese

dum sinal de fala produzido pelo descodificador AMR.

Page 20: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 19

Pedro Mota | Pedro Santos

Figura 4: Diagrama de blocos simplificado do descodificador de voz AMR.

Aqui, dependendo do modo escolhido, os índices transmitidos são extraídos do

bitstream recebido. Estes índices são descodificados para obter os parâmetros de

codificação a cada frame transmitida. Os parâmetros são os vectores LSP, os atrasos

fraccionários do pitch, o codebook inovativo e os ganhos do pitch e codebook inovativo.

Os vectores LSP são convertidos nos coeficientes do filtro LP e interpolados para

obter filtros LP em cada subframe. Então, a cada 40 amostras (subframe) é realizado o

seguinte:

• A excitação é construída por adição do codebook inovativo e adaptativo escalados

dos seus respectivos ganhos;

• O sinal de fala é reconstruído por filtragem da excitação através do filtro de síntese

LP.

Finalmente, o sinal de fala reconstruído é filtrado por uma pós-filtragem adaptativa.

3.4 Detector de presença de voz (VAD)

O algoritmo VAD (voice activity detector) usa os parâmetros do codificador de voz

para calcular uma flag que simplesmente indique a presença ou não de um sinal de voz.

LSPindices

decode LSP

interpolation of LSP for the4 subframes

LSP

decodeadaptivecodebook

decodeinnovativecodebook

pitchindex

codeindex

decodegains

A(z)^

constructexcitation

frame subframe post-processing

s'(n)^s(n)^post filter

gainsindices

synthesisfilter

Page 21: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 20

Pedro Mota | Pedro Santos

No esquema seguinte pode-se ver um diagrama de blocos representativo deste

algoritmo.

Filter bankandcomputationof sub-bandlevels

VADdecision

Pitchdetection

Tonedetection

T_op[n]

t0,t1

VAD_flag

level[n]

pitch

tone

s(i)

Complexsignalanalysis

OL-LTPcorrelationvector

complex_warningTonedetectiont0,t1

complex_timer

Figura 5: Diagrama de blocos simplificado do algoritmo VAD.

Amostras da frame de entrada, s(i), são divididas em sub-bandas e o nível do sinal

para cada sub-banda é então calculado.

A entrada do bloco de detecção de pitch, T_op[n], é o resultado do atraso do pitch

calculado no codificador de voz. Este bloco calcula uma flag (pitch) que indica a presença

ou não de pitch.

O bloco de detecção de tom calcula uma flag (tone), que indica a presença de um

tom de informação. Tons são detectados tendo como base o ganho de pitch obtido na

análise em open-loop pelo codificador de voz.

A detecção de sinais complexos calcula uma flag (complex_warning), indicando a

presença de sinais complexos como, por exemplo, música. Esta detecção é feita tendo

como base o vector de correlação disponível na análise em open-loop do pitch.

A função de decisão de VAD estima níveis de ruído de fundo. Estes níveis são

comparados com os níveis da frame de entrada (level[n]) por forma a tomar-se uma

decisão intermédia. Finalmente, a decisão final é tomada tendo em consideração decisões

tomadas anteriormente.

Page 22: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 21

Pedro Mota | Pedro Santos

3.5 Controlo do débito (SCR)

A operação SCR (source controlled rate) é o mecanismo que permite a um

codificador de voz AMR codificar com um débito médio inferior, tendo em conta os

períodos de inactividade de voz. Este esquema é particularmente útil para se poder poupar

energia nos equipamentos terminais, uma vez que quando não há actividade de voz, o

processamento sobre o sinal fica simplificado para reduzir cargas de débitos a que as redes

de comunicações ficam sujeitas.

Esta operação requer do lado do emissor um detector de voz e um avaliador do

ruído de fundo a ser transmitido. Do lado de receptor terá que existir um gerador de ruído

de fundo (ruído de conforto), durante os períodos onde a transmissão está desligada.

No esquema seguinte pode ver-se uma ligação entre emissor e receptor

usando uma operação SCR.

RX_TYPE

Mode Indication

Information bits

TX SCR handler

SpeechEncoder

VoiceActivityDetector

Comfort NoiseParameter

Computation

“Network”

Informationpacketing,

transport andclassification

Information bits

Mode Indication

TX_TYPE

RX SCR handler

SpeechDecoder

ErrorConcealment

ComfortNoise

Generation

Figura 6: Diagrama de blocos de uma ligação com operação SCR.

De notar que, em adição a estas funcionalidades, se os parâmetros chegados ao

receptor forem detectados como estando seriamente corrompidos por erros, o sinal de fala

ou de ruído de conforto deve ser substituído por outros dados de forma a evitar efeitos

desagradáveis para o ouvinte.

3.6 Código C para o codec de voz AMR

Esta é a parte da norma que engloba as diferentes componentes que constituem o

codec AMR. Aqui, foi realizada uma implementação em vírgula fixa das funções que

codificam a voz, o detector de presença de voz, ruído de conforto, controlo de débito e

substituição de frames perdidas.

Page 23: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 22

Pedro Mota | Pedro Santos

De salientar que é esta parte da norma que realmente define todo o codec de voz

AMR, ou seja, em caso de incoerência por parte de alguma descrição que seja feita do

codec face ao que é realmente feito na sua versão em código C, prevalece este último.

3.6.1 Conteúdos do código C

Os ficheiros que constituem o código C, distribuem-se em 3 tipo: os com o sufixo

‘c’ com o código propriamente dito e os respectivos header files com sufixo ‘h’. Os dados

encontram-se, de uma forma geral, nos ficheiros com o sufixo ‘tab’.

Para se proceder à instalação do programa basta correr o makefile que acompanha

os restantes ficheiros. Uma vez instalado o software, são gerados dois executáveis: encoder

e decoder, responsáveis respectivamente pela codificação e descodificação dum sinal de

acordo com a norma AMR.

Para além disto, existem ficheiros para verificar a correcta instalação do codificador

e descodificador. Destes, interessam os ficheiros spch_dos.inp, spch_dos.cod e

spch_dos.out, que são respectivamente ficheiros de entrada de um sinal de áudio, a sua

versão codificada e à saída do descodificador.

Para se testar a instalação realizado é fornecido um script que automaticamente

corre o programa instalado comparando os resultados obtidos com os dos ficheiros

descritos anteriormente. Este script encontra-se no ficheiro amr_chk.csh que deve ser

chamado numa shell da seguinte forma: ‘./amr_chk.csh dos’.

A instalação correcta do código num PC correu sem dar qualquer tipo de

problemas.

3.6.2 Execução do programa

A execução do codificador e descodificador deve ser realizada da seguinte forma:

- encoder [options] amr_mode input_file bitstream_file; amr_mode = MR475 4.75 kbit/s

MR515 5.15 kbit/s MR59 5.90 kbit/s MR67 6.70 kbit/s MR74 7.40 kbit/s MR795 7.95 kbit/s MR102 10.20 kbit/s MR122 12.20 kbit/s

options = -dtx habilita operação com débito variável

Page 24: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 23

Pedro Mota | Pedro Santos

- decoder [option] bitstream_file output_file; option = -rxframetype esperada frame RX em vez de TX. Útil apenas para simulações com outros componentes entre codificador e descodificador.

Os ficheiros de fala contêm dados de amostras em formato PCM de 16 bits e

ficheiros de bitstream os dados codificados e algumas flags adicionais.

3.6.3 Estrutura do código

O código C é estruturado seguindo a seguinte estrutura. Cada função que necessita

de variáveis estáticas é considerada um módulo. Este módulo consiste em:

- uma estrutura (struct) combinando as diversas variáveis do módulo;

- três funções auxiliares: func_init(), func_reset() e func_exit();

- o processamento da função func() propriamente dita.

A inicialização da função func_init() aloca um novo estado da estrutura, chama a

função func_reset(), guarda o apontador que aponta para a nova estrutura alocada e retorna

o valor de 0 se a operação correu bem ou 1 caso contrário.

A função de reset, func_reset(), utiliza o apontador da estrutura em causa colocando

os seus membros para um valor predefinido.

A função exit, func_exit(), realiza a libertação de memória que tinha sido

previamente realizada.

A função propriamente dita, func(), pega nesse apontador assim como outros

parâmetros fundamentais, e realiza as operações necessárias para obter os resultados finais

que podem passar pela alteração dos campos dessa estrutura.

Um módulo pode chamar outro módulo. Neste caso, o de maior nível terá que

conter um apontador para o de menor nível e as funções de init, reset e exit são chamadas

recursivamente.

Nas duas tabelas seguintes é possível ver-se todas as estruturas que existem ao

longo dos programas de codificação e descodificação.

Page 25: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 24

Pedro Mota | Pedro Santos

Struct name Variable Type[Length] Description Speech_Encode_ FrameState

cod_amr_state cod_amrState see below in this table

pre_state Pre_ProcessState see below in this table dtx Flag Is set if DTX functionality is used complexityCounter int Used for wMOPS counting Pre_ProcessState y2_hi Word16 filter state, upper word y2_lo Word16 filter state, lower word y1_hi Word16 filter state, upper word y1_lo Word16 filter state, lower word x0 Word16 filter state x1 Word16 filter state cod_amrState old_speech Word16[320] speech buffer speech Word16* pointer to current frame in old_speech p_window Word16* pointer to LPC analysis window in old_speech p_window_12k2 Word16* pointer to LPC analysis window with no lookahead

in old_speech (MR122) new_speech Word16* pointer to the last 160 speech samples in

old_speech old_wsp Word16[303] buffer holding spectral weighted speech wsp Word16* pointer to the current frame in old_wsp old_lags Word16[5] open loop LTP states ol_gain_flg Word16[2] enables open loop pitch lag weighting (MR102) old_exc Word16[314] excitation vector exc Word16* current excitation ai_zero Word16[51] history of weighted synth. filter followed by zero

vector zero Word16* zero vector h1 Word16* impulse response of weighted synthesis filter hvec Word16[80] zero vector followed by impulse response lpcSt lpcState see below in this table lspSt lspState see below in this table clLtpSt clLtpState see below in this table gainQuantSt gainQuantState see below in this table pitchOLWghtSt pitchOLWghtState see below in this table tonStabSt tonStabState see below in this table vadSt vadState1 see below in this table vadSt vadState2 see below in this table dtx Flag is set if DTX functionality is used dtx_encSt dtx_encState see below in this table mem_syn Word16[10] synthesis filter memory mem_w0 Word16[10] weighting filter memory (applied to error signal) mem_w Word16[10] weighting filter memory (applied to input signal) mem_err Word16[50] filter memory for production of error vector error Word16* error signal (input minus synthesized speech) sharp Word16 pitch sharpening gain vadState1 bckr_est Word16[9] background noise estimate ave_level Word16[9] averaged input components for stationary

estimation old_level Word16[9] input levels of the previous frame sub_level Word16[9] input levels calculated at the end of a frame

(lookahead) a_data5 Word16[6] memory for the filter bank a_data3 Word16[5] memory for the filter bank burst_count Word16 counts length of a speech burst hang_count Word16 hangover counter stat_count Word16 stationary counter vadreg Word16 15 flags for intermediate VAD decisions pitch Word16 15 flags for pitch detection tone Word16 15 flags for tone detection complex_high Word16 flags for complex detection complex_low Word16 flags for complex detection oldlag_count Word16 variables for pitch detection oldlag Word16 variables for pitch detection complex_hang_count Word16 complex hangover counter, used by VAD complex_hang_timer Word16 hangover initiator, used by CAD

Page 26: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 25

Pedro Mota | Pedro Santos

Struct name Variable Type[Length] Description best_corr_hp Word16 filtered value speech_vad_decision Word16 final decision complex_warning Word16 complex background warning sp_burst_count Word16 counts length of a speech burst incl HO addition corr_hp_fast Word16 filtered value vadState2 pre_emp_mem Word16 input pre-emphasis memory update_cnt Word16 noise update counter hyster_cnt Word16 hysteresis counter last_update_cnt Word16 noise update counter value for last frame ch_enrg_long_db Word16[16] long term channel energy in dB Lframe_cnt Word32 10 ms frame counter Lch_enrg Word32[16] channel energy estimate Lch_noise Word32[16] channel noise estimate last_normb_shift Word16 block shift factor for last frame, used for

pre_emp_mem tsnr Word16 total estimated peak SNR in dB hangover Word16 VAD hangover burstcount Word16 number of consecutive voice active frames fupdate_flag Word16 A flag to control a forced update of the noise

estimate negSNRvar Word16 SNR variability negSNRbias Word16 sensitivity bias shift_state Word16 indicates scaling state of channel energy estimate L_R0 Word32 LTP energy L_Rmax Word32 LTP max correlation LTP_flag Flag set when open loop pitch prediction gain >

threshold dtx_encState lsp_hist Word16[80] LSP history (8 frames) log_en_hist Word16[8] logarithmic frame energy history (8 frames) hist_ptr Word16 pointer to the cyclic history vectors log_en_index Word16 Index for logarithmic energy init_lsf_vq_index Word16 initial index for lsf predictor lsp_index Word16[3] lsp indecies to the three code books dtxHangoverCount Word16 is decreased in DTX hangover period decAnaElapsedCount Word16 counter for elapsed speech frames in DTX lpcState LevinsonSt LevinsonState see below LevinsonState old_A Word16[11] last frames direct form coefficients lspState lsp_old Word16[10] old LSP vector lsp_old_q Word16[10] old quantized LSP vector qSt Q_plsfState see below in this table Q_plsfState past_rq Word16[10] past quantized LSF prediction error clLtpState pitchSt Pitch_frState see below in this table tonStabState count Word16 count consecutive (potential) resonance frames gp Word16[7] pitch gain history Pitch_frState T0_prev_subframe Word16 integer. pitch lag of previous subframe gainQuantState sf0_exp_gcode0 Word16 subframe 0/2 codebook gain exponent sf0_frac_gcode0 Word16 subframe 0/2 codebook gain fraction sf0_exp_target_en Word16 subframe 0/2 target energy exponent sf0_frac_target_en Word16 subframe 0/2 target energy fraction sf0_exp_coeff Word16[5] subframe 0/2 energy coefficient exponents sf0_frac_coeff Word16[5] subframe 0/2 energy coefficient fractions gain_idx_ptr Word16* pointer to gain index value in parameter frame gc_predSt gc_predState see below in this table gc_predUncSt gc_predState see below in this table adaptSt GainAdaptState see below in this table gc_predState past_qua_en Word16[4] MA predictor memory (20*log10(pred. error)) past_qua_en_MR122 Word16[4] MA predictor memory, 12.2 style (log2(pred.

error)) GainAdaptState onset Word16 onset counter prev_alpha Word16 previous adaptor output prev_gc Word16 previous codebook gain ltpg_mem Word16[5] pitch gain history

Page 27: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 26

Pedro Mota | Pedro Santos

Struct name Variable Type[Length] Description pitchOLWghtState old_T0_med Word16 weighted open loop pitch lag ada_w Word16 weigthing level depeding on open loop pitch gain wght_flg Word16 switches lag weighting on and off

Tabela 2: Estruturas existentes no codificador de voz AMR.

Struct name Variable Type[Length] Description Speech_Decode_FrameState

decoder_amrState Decoder_amrState see below in this table

post_state Post_FilterState see below in this table postHP_state Post_ProcessState see below in this table ComplexityCounter int Used for wMOPS counting Decoder_amrState old_exc Word16[194] excitation vector exc Word16* current excitation lsp_old Word16[10] LSP vector of previous frame mem_syn Word16[10] synthesis filter memory sharp Word16 pitch sharpening gain old_T0 Word16 pitch sharpening lag prev_bf Word16 previous value of "bad frame" flag prev_pdf Word16 previous value of "pot. dangerous frame" flag state Word16 ECU state (0..6) excEnergyHist Word16[9] excitation energy history T0_lagBuff Word16 received pitch lag for ECU inBackgroundNoise Word16 background noise flag voicedHangover Word16 hangover flag ltpGainHistory Word16[9] pitch gain history background_state Bgn_scdState see below in this table Cb_gain_averState Cb_gain_averageStat

e see below in this table

lsp_avg_st lsp_avgState see below in this table lsfState D_plsfState see below in this table ec_gain_p_st ec_gain_pitchState see below in this table ec_gain_c_st ec_gain_codeState see below in this table pred_state gc_predState see table 7 nodataSeed Word16 seed for CN generator ph_disp_st ph_dispState see below in this table dtxDecoderState dtx_decState see below in this table dtx_decState since_last_sid Word16 number of frames since last SID frame true_sid_period_inv Word16 inverse of true SID update rate log_en Word16 logarithmic frame energy old_log_en Word16 previous value of log_en L_pn_seed_rx Word32 random number generator seed lsp Word16[10] LSP vector lsp_old Word16[10] previous LSP vector lsf_hist Word16[80] LSF vector history (8 frames) lsf_hist_ptr Word16 index to beginning of LSF history lsf_hist_mean Word16[80] mean-removed LSF history (8 frames) log_pg_mean Word16 mean-removed logarithmic prediction gain log_en_hist Word16[8] logarithmic frame energy history log_en_hist_ptr Word16 index to beginning of log, frame energy

history log_en_adjust Word16 mode-dependent frame energy adjustment dtxHangoverCount Word16 counts down in hangover period decAnaElapsedCount Word16 counts elapsed speech frames after DTX sid_frame Word16 flags SID frames valid_data Word16 flags SID frames containing valid data dtxHangoverAdded Word16 flags hangover period at end of speech dtxGlobalState enum DTXStateType DTX state flags data_updated Word16 flags CNI updates Bgn_scdState frameEnergyHist Word16[60] history of synthesis frame energy bgHangover Word16 number of frames since last speech frame

Page 28: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 27

Pedro Mota | Pedro Santos

Struct name Variable Type[Length] Description Cb_gain_averageState cbGainHistory Word16[7] codebook gain history hangVar Word16 counts length of talkspurt in subframes hangCount Word16 number of subframes since last talkspurt lsp_avgState lsp_meanSave Word16[10] averaged LSP vector D_plsfState past_r_q Word16[10] past quantized LSF prediction vector past_lsf_q Word16[10] past dequantized LSF vector ec_gain_pitchState pbuf Word16[5] pitch gain history past_gain_pit Word16 previous pitch gain (limited to 1.0) prev_gp Word16 previous good pitch gain ec_gain_codeState gbuf Word16[5] codebook gain history past_gain_code Word16 previous codebook gain prev_gc Word16 previous good codebook gain ph_dispState gainMem Word16[5] pitch gain history prevState Word16 previously used impulse response prevCbGain Word16 previous codebook gain lockFull Word16 force maximum phase dispersion onset Word16 onset counter Post_FilterState res2 Word16[40] LP residual mem_syn_pst Word16[10] synthesis filter memory synth_buf Word16[170] synthesis filter work area agc_state agcState see below in this table preemph_state preemphasisState see below in this table agcState past_gain Word16 past agc gain preemphasisState mem_pre Word16 filter state Post_ProcessState y2_hi Word16 filter state, upper word y2_lo Word16 filter state, lower word y1_hi Word16 filter state, upper word y1_lo Word16 filter state, lower word x0 Word16 filter state x1 Word16 filter state

Tabela 3: Estruturas existentes no descodificador de voz AMR.

3.6.4 Hierarquia do código

As quatro tabelas seguintes mostram toda a sequência de chamadas às funções

existentes no código da norma do codec AMR. Estes quadros devem ser lidos da esquerda

para a direita à medida que nível que o profundidade da chamada das funções vai sendo

aumentando.

Page 29: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 28

Pedro Mota | Pedro Santos

Speech_Encode_Frame Pre_Process cod_amr Copy Vad1 filter_bank first_filter_stage filter5 filter3 level_calculation vad_decision complex_estimate_adapt complex_vad noise_estimate_update update_cntrl hangover_addition tx_dtx_handler lpc Autocorr Lag_window Levinson lsp Az_lsp Chebps Q_plsf_5 Lsp_lsf Lsf_wt Vq_subvec Vq_subvec_s Reorder_lsf Lsf_lsp Int_lpc_1and3_2 Lsp_az Get_lsp_pol Int_lpc_1and3 Lsp_az Get_lsp_pol Q_plsf_3 Lsp_lsf Lsf_wt Copy Vq_subvec3 Vq_subvec4 Reorder_lsf Lsf_lsp Int_lpc_1to3_2 Lsp_az Get_lsp_pol Int_lpc_1to3 Lsp_az Get_lsp_pol Copy dtx_buffer Copy Log2 Log2_norm dtx_enc Lsp_lsf Reorder_lsf Lsf_lsp Set_zero lsp_reset Copy Q_plsf_reset cl_ltp_reset Pitch_fr_reset check_lsp pre_big Weight_Ai Residu Syn_filt ol_ltp Pitch_ol vad_tone_detection_update Lag_max vad_tone_detection Inv_sqrt comp_corr hp_max2 vad_complex_detection_update Pitch_ol_wgh comp_corr Lag_max vad_tone_detection_update vad_tone_detection gmed_n hp_max vad_complex_detection_update vad_pitch_detection subframePreProc Weight_Ai Syn_filt Residu Copy cl_ltp Pitch_fr getRange Norm_Corr Convolve Inv_sqrt searchFrac Interpol_3or6 Enc_lag3 Enc_lag6 Pred_lt_3or6 Convolve G_pitch check_gp_clipping q_gain_pitch cbsearch ver Tabela 5 gainQuant ver Tabela 6 update_gp_clipping Copy subframePostProc Syn_filt Pred_lt_3or6 Convolve Prm2bits Int2bin

Tabela 4: Estrutura da chamada das funções do codificador.

Page 30: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 29

Pedro Mota | Pedro Santos

cbsearch code_2i40_9bits cor_h_x set_sign cor_h Inv_sqrt search_2i40 build_code code_2i40_11bits cor_h_x set_sign cor_h Inv_sqrt search_2i40 build_code code_3i40_14bits cor_h_x set_sign cor_h Inv_sqrt search_3i40 build_code code_4i40_17bits cor_h_x set_sign cor_h Inv_sqrt search_4i40 build_code code_8i40_31bits cor_h_x set_sign12k2 Inv_sqrt cor_h Inv_sqrt search_10and8i40 build_code compress_code compress10 code_10i40_35bits cor_h_x set_sign12k2 Inv_sqrt cor_h Inv_sqrt search_10and8i40 build_code q_p

Tabela 5: Estrutura da chamada das funções da função cbsearch.

gainQuant gc_pred_copy Copy gc_pred Log2 Log2_norm Log2_norm calc_filt_energies calc_target_energy MR475_update_unq_pred gc_pred_update MR475_gain_quant MR475_quant_store_results Log2 Log2_norm gc_pred_update gc_pred Log2 Log2_norm Log2_norm G_code q_gain_code Pow2 MR795_gain_quant q_gain_pitch MR795_gain_code_quant3 calc_unfilt_energies Log2 Log2_norm gain_adapt gmed_n MR795_gain_code_quant_mod sqrt_l_exp Qua_gain Pow2 gc_pred_update

Tabela 6: Estrutura da chamada das funções da função gainQuant.

Page 31: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 30

Pedro Mota | Pedro Santos

Speech_Decode_Frame Bits2prm Bin2int Decoder_amr rx_dtx_handler Decoder_amr_reset lsp_avg_reset D_plsf_reset ec_gain_pitch_reset ec_gain_code_reset gc_pred_reset Bgn_scd_reset Set_zero ph_disp_reset dtx_dec_reset Copy Set_zero dtx_dec Copy Lsf_lsp Init_D_plsf_3 Copy D_plsf_3 Reorder_lsf Copy Lsf_lsp pseudonoise Lsp_lsf Reorder_lsf Lsp_Az Get_lsp_pol A_Refl Log2 Log2_norm Build_CN_code pseudonoise Syn_filt Lsf_lsp lsp_avg Copy D_plsf_3 Reorder_lsf Copy Lsf_lsp Int_lpc_1to3 Lsp_Az Get_lsp_pol D_plsf_5 Reorder_lsf Copy Lsf_lsp Int_lpc_1and3 Lsp_Az Get_lsp_pol Dec_lag3 Pred_lt_3or6 Dec_lag6 decode_2i40_9bits decode_2i40_11bits decode_3i40_14bits decode_4i40_17bits decode_8i40_31bits decompress_code decompress10 ec_gain_pitch gmed_n d_gain_pitch ec_gain_pitch_update decode_10i40_35bits Dec_gain Log2 Log2_norm gc_pred Log2 Log2_norm Log2_norm Pow2 gc_pred_update ec_gain_code gmed_n gc_pred_average_limeted gc_pred_update ec_gain_code_update d_gain_code gc_pred Log2 Log2_norm Log2_norm Pow2 gc_pred_update Int_lsf Cb_gain_average ph_disp_release ph_disp_lock ph_disp sqrt_l_exp Ex_ctrl gmed_n agc2 Inv_sqrt Syn_filt Bgn_scd gmed_n dtx_dec_activity_update Copy Log2 Log2_norm lsp_avg Post_Filter Copy Weight_Ai Residu Set_zero Syn_filt Preemphasis agc energy_old energy_new energy_old Inv_sqrt Post_Process

Tabela 7: Estrutura da chamada das funções do descodificador.

Page 32: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 31

Pedro Mota | Pedro Santos

4 OpenRISC 1200 RISC/DSP Core

4.1 Descrição do OpenRISC 1200 Core

A arquitectura do processador OpenRISC 1200 é de domínio público, constituindo

a base para as famílias de processadores do tipo RISC/DSP de 32-bit e 64-bit. Esta foi

desenhada com o objectivo de implementar um sistema capaz de ter consumo de potência

reduzido, simplicidade, versatilidade , reduzida área, capaz de servir aplicações a nível de

redes e de SoC.

As principais potencialidades deste processador incluem a existência de instruções

do tipo DSP e Floating point e na versão de 64-bit instruções vectoriais. Possui ainda

suporte para memória virtual, quer de dados quer de instruções, cache de dados e de

instruções, e suporte para SMP (Symmetrical Multi-Processing) e SMT (Simultaneous

Multi-Treading).

Salientem-se ainda certas features dedicadas para funcionamento em rede e em

sistemas embebidos, sendo que as mais notáveis são um número configurável de registos,

cache e tamanhos das TLB (Translation Lookaside Buffer) configuráveis, controlo

dinâmico da potência dinâmica e espaço para implementação de instruções fornecidas pelo

utilizador.

Numa perspectiva de alto nível este processador pode ser apresentado como um

conjunto de unidades modulares. Esse esquema está apresentado na Figura 7

Figura 7 - OpenRISC 1200 Core

Page 33: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 32

Pedro Mota | Pedro Santos

O Or1k funciona com instruções ORBIS32 (OpenRISC based instruction set) pelo

que a sua arquitectura é de 32-bit.

Este processador tem uma pipeline de 5 andares (single-issue 5-stage), e a maior

parte das suas instruções são executadas num único ciclo de relógio.

Em termos das suas interrupções internas, o Or1k tem a capacidade de responder

rapidamente e deterministicamente a estas mesmas. Existem no processador 32 registos

para uso geral de 32-bits.

Pode referir-se ainda que existe uma unidade de DSP/MAC integrada, que permite

multiplicações entre operandos de 32-bits e com acumulador de 48-bits.

Das implementações físicas que se fizeram deste processador em tecnologia

específica foram obtidos 250 MHZ usando como dimensões mínimas 0.18u com 6

camadas de metal.

O Or1k é optimizado apara integrar aplicações do tipo system-on-chip, que

correspondem a sistemas embebidos.

De forma sumária poder-se-á dizer que este processador serve aplicações que

necessitem da performance de processadores de 32-bits em relação aos de 16, e em que

factores como o consumo de potência e custo são determinantes.

Para uma descrição mais detalhada relativa ao funcionamento de cada uma destas

secções deve ser consultada tanto o manual que descreve a arquitectura deste processador,

como o documento que contém as especificações do Or1k.

Pretende-se nas secções seguintes fazer uma apresentação de cada um dois blocos

que se encontra presente na figura e que pode caracterizar o processador.

4.1.1 CPU/DSP

O esquema seguinte representa de forma mais detalhada o CPU/DSP.

Page 34: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 33

Pedro Mota | Pedro Santos

Figura 8 - Blocos que constituem o CPU/DSP Core

Este bloco representa a parte central do processador OR1200 RISC. Esta versão

apenas suporta 32-bit. Operações em vírgula flutuante não são suportadas, assim como as

que têm carácter vectorial.

Ter-se-á o cuidado de descrever cada um dos blocos que constitui a parte central

deste CPU.

4.1.1.1 Unidade de Instruções

A unidade de instruções implementa a pipeline básica das instruções, que as carrega

a partir do subsistema da memória, direcciona-as para unidades válidas de execução, e

mantém um histórico do seu estado, de modo a poder assegurar um modelo preciso de

excepções e que as operações sejam terminadas com a ordem correcta.

Também deve ser capaz de distinguir quando é que os dados estão disponíveis e

certificar-se que não existe outra instrução a querer aceder ao mesmo registo de destino.

Esta unidade suporta instruções da classe ORBIS32.

4.1.1.2 Registos para uso genérico (GPR)

O OpenRISC 1200 possui, como referido na descrição sumária, 32 registos de 32-

bits para uso genérico. A arquitectura que lhe está associada permite a cópia para um

ficheiro que contém a informação sobre estes registos e que possibilita a rápida comutação

entre ambientes de trabalho.

Este ficheiro de registo é implementado como uma memória dual-port com a

capacidade de 32 palavras por 32 bits por palavra.

Page 35: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 34

Pedro Mota | Pedro Santos

4.1.1.3 Unidade de Load/Store

A unidade Load/Store transfere todos os dados entre os GPRs e o bus interno do

CPU. Esta foi implementada como unidade de execução independente, de modo que

paragens que estejam a ocorrer no subsistema de memória só afectarão a pipeline principal

se apenas existir dependência entre os dados.

As principais features referem-se a uma implementação exclusiva de todas as

unidades de load e store apenas em hardware, buffer para os endereços de entrada,

operação em pipeline e alinhamento de endereços para acessos rápidos à memória.

Sempre que é necessário realizar uma instrução, quer de load, quer de store, a LSU

verifica se todos os operandos estão disponíveis. Estes são os seguintes: operando com o

registo do endereço, operando com o registo dos dados( para instruções de store), operando

com os registos de dados do destino ( para instruções de load).

4.1.1.4 Excepções

As excepções no core são geradas quando existe uma fonte a indicar que ocorreu

uma situação especial, como é o caso das interrupções externas, certos acessos a memória

ou erros internos como é o caso da execução de opcode de instruções que não estão

presentes no Or1k, chamadas do sistema, ou ainda excepções internas como é o caso de

breakpoints.

Quando uma determina excepção ocorre, o controlo é transferido para um handler

capaz de a atender. Assim, o Program Counter deve ser carregado com o endereço onde o

handler se localiza.

O tratamento destas excepções é realizado apenas no modo de supervisão.

4.1.1.5 System Unit

A unidade do sistema conecta todos os outros sinais do CPU/DSP que não estão

ligados directamente às interfaces de dados e de instruções. Implementa também todos os

registos especiais que estão estritamente ligados com o sistema, como é o caso do registo

de supervisão.

4.1.1.6 Pipeline e MAC Unit

É de salientar o carácter das várias instruções inteiras que podem ser realizadas

nesta unidade como é o caso das aritméticas, de comparação, lógicas, e as que realizam as

rotações e shifts sobre os operandos.

Page 36: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 35

Pedro Mota | Pedro Santos

A maior parte destas instruções pode ser executada apenas num único ciclo de

relógio.

4.1.1.7 DSP MAC

A unidade de MAC executa operações do tipo DSP MAC, optimizadas para o

cálculo do processamento do sinal. Esta unidade permite multiplicações entre operandos de

32-bits, possuindo um acumulador de 48-bits.

4.1.2 Caches

É conveniente realizar a caracterização das caches. As caches usadas neste

processador seguem o modelo de Harvard pois é realizada a separação entre a cache de

dados e de instruções. As caches, quer de dados quer de instruções, são de uma única

entrada e mapeadas directamente.

Há a possibilidade de poder desactivar ou invalidar as caches através da escrita de

registos especiais destinados a esta mesma função.

A cache usando a configuração padrão está organizada em 512 linhas, sendo que

cada linha consiste em 16 bytes de dados, bits de estado e endereço da tag.

A cache é preenchida através de bursts de 16 bytes sempre que a tag e os bits

correspondentes no endereço são diferentes.

Neste preenchimento a palavra crítica é escrita simultaneamente na cache e

direccionada para a unidade que realizou o pedido, o que minimiza as paragens devido à

latência associado ao preenchimento da cache.

Para o caso da cache de dados, esta permite que as tags sejam armazenadas e

executa a substituição das linhas.

No caso da cache de instruções, ela comunica com a unidade de fetch de forma

adequada, de modo que esta última permite o cálculo do endereço efectivo.

As caches quer de dados quer de instruções estão acopladas fortemente com a

interface exterior para que a eficiência no acesso ao controlador de memória seja máxima.

Page 37: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 36

Pedro Mota | Pedro Santos

Word n

Byte pos.

Word n+1

Byte pos.

Word n+2

Byte pos.

Word n+3

Byte pos.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Tag

Address State Bits

Número de linhas que constitui a cache

Figura 9: Estrutura da cache

A configuração de default das caches é de 8KB, sendo possível ter valores para a

sua dimensão de 1KB até 8Kyte, o que indica – admitindo bursts de 16 bytes – que teremos

64 e 512 linhas respectivamente.

4.1.3 Memory Management Unit

O Or1k está dotado de memória virtual, realizando a separação entre dados e

instruções no tratamento da memória virtual, adoptando-se uma arquitectura do tipo

Harvard para a mesma.

O valor para o tamanho do TLB é variável entre 16 e 256 entradas, quer para o caso

de dados quer para o caso de instruções, sendo este por default de uma única entrada.

O espaço de endereçamento é linear sendo que os endereços virtuais são de 32 bits

e os endereços físicos de 24 a 32-bits.

Existe ainda um esquema que trata da protecção das páginas. O tamanho das

páginas é de 8KB estando inerente a cada uma delas os respectivos atributos.

4.1.4 Power Management Unit

Uma grande potencialidade integrada neste processador é a unidade que permite a

redução do consumo de potência. Esta é capaz de reduzir o consumo de 2x a 100x. É

possível ainda fazer o controlo da frequência do relógio no modo de funcionamento de

baixa velocidade e no modo de idle.

Com esta unidade é possível activar dispositivos que estavam adormecidos, através

de uma interrupção. Tem incorporado clock gating de modo que o sinal de clock só seja

recebido por determinadas unidades se o sinal de controlo estiver activo.

Page 38: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 37

Pedro Mota | Pedro Santos

4.1.5 Unidade de Debug

O Or1k tem incorporado uma unidade que permite a realização de debug

convencional.

O modo de Debug não interfere com o funcionamento do RISC e do sistema. A

unidade de debug permite que se faça o supervisionamento do RISC e do sistema em

tempo real.

É possível ter acesso ao controlo da unidade que permite realizar o depuramento

quer seja a partir do RISC quer seja a partir do interface de desenvolvimento.

4.1.6 Tick Timer Integrado

O Or1k tem implementado internamente um tick timer que está ligado directamente

ao relógio do RISC e que é usado pelo sistema operativo para fazer a medição precisa do

tempo e agendar tarefas do sistema.

O temporizador permite que se faça a contagem de 2^32 ciclos de relógio. Entre

interrupções o período máximo entre estas é de 2^28. Possui ainda uma máscara que faz a

configuração deste mesmo registo.

O timer tem ainda como outra feature vários modos de operação: single run

gerando uma única interrupção; continues timer, onde estão a ser geradas temporizações

bem determinadas. É possível executar ainda o reset deste mesmo timer.

4.1.7 Programmable Interrupt Controller

Este controlador de interrupções recebe interrupções externas direccionando-as para

o CPU core, atribuindo-lhes níveis de prioridade. Existem duas interrupções que não

podem ser desactivadas, respectivamente a 0 e a 1. No total existem 32 interrupções,

estando disponíveis apenas 30 pelas razões já referidas. Estas 30 interrupções podem ser

mascaradas de forma a servirem os objectivos de determinada aplicação.

Deve ser mencionado que existem 3 registos associados ao PIC que fazem a sua

configuração e que se englobam no conjunto de registos especiais.

4.1.8 Unidades Adicionais E Definidas Pelo Utilizador

Os responsáveis pelo desenvolvimento deste mesmo processador permitiram que

unidades adicionais fossem incorporadas e que fossem introduzidas como unidades

standard.

Page 39: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 38

Pedro Mota | Pedro Santos

No total é possível introduzir 8 unidades que podem ser controladas através de

registos especiais presentes ou instruções dedicadas.

4.1.9 Ferramentas De Suporte Ao Desenvolvimento

As ferramentas que devem ser mencionadas referem os compiladores GNU ANSI

C, C++, Java e Fortran.

Existem ainda o GNU debugger, linker, assembler, utilities e um simulador

dedicado à arquitectura.

Será dedicado neste documento uma secção a estas ferramentas, pois constituem o

suporte para o desenvolvimento deste mesmo projecto.

4.1.10 Sistemas Operativos Suportados:

O Or1k é capaz de suportar como sistemas operativos o Linux, o UClinux, e OAR

RTEMS real-time OS.

4.1.11 Interface do Sistema

O protocolo de comunicação que tem incorporado designa-se Wishbone. O

protocolo permite fluxo de dados bidireccional e com reduzida latência.

O sistema construído com base no Or1k é ainda dotado de uma interface dual, ou

seja, existe fluxo de execução de dados e de instruções simultâneo, o que, de facto, é uma

enorme vantagem em cadeias de processamento exigentes.

Existem ainda vários cores desenvolvidos e que podem ser ligados de forma

transparente ao Or1k, como é o caso de controladores de memória, Uarts, GPIOS.

4.2 Nível de transferência lógica de registos do OR1200

Para simular e posteriormente realizar a síntese física do OpenRISC 1200 é

necessário ter acesso ao código fonte descrito em Verilog.

Para esta operação existem duas alternativas: - usar o comando cvs integrado em

plataformas que usam o sistema operativo Linux (disponível também em emuladores de

Linux para Windows), ou fazer o download através da ferramenta CvsGet presente em

www.opencores.org.

Para obter os ficheiros, usando o comando cvs, deve ser corrido o seguinte script:

export CVSROOT=:pserver:[email protected]:/home/oc/cvs cvs –z9 co or1k/or1200/

Page 40: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 39

Pedro Mota | Pedro Santos

Assim na pasta or1k/or1200 estará todo o código fonte que é necessário para

realizar as operações de simulação e de síntese.

Caso o método para obter o código fonte seja o CvsGet, deve na página web seguir

o link CvsGet e colocar no campo que permite escolher o módulo, or1k/or1200. A figura

seguinte mostra de forma mais clara como realizar esta tarefa.

Figura 10 – CvsGet da página www.opencores.org

A revisão pode ser opcional, sendo por default obtida a mais recente das versões.

Pode-se alternativamente usar o WinCvs para ter acesso a esta informação.

Dos ficheiros que existem disponíveis há alguns que merecem especial atenção,

como é o caso do top-level do CPU/DSP core, or1200_cpu .v, o top-level do sistema que

inclui o módulo anterior, – or1200_top.v – e os restantes periféricos referidos na figura

Figura 7 deste documento, assim como o ficheiro or1200_defines.v que contém as macros

que controlam o comportamento do sistema e as features que estão implementadas.

Assim, por exemplo, é possível escolher se a cache de dados está ou não

implementada, e, caso esteja, qual o seu tamanho e realizar a configuração de registos que

são responsáveis pelo comportamento da mesma, através das macros que estão activas.

Page 41: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 40

Pedro Mota | Pedro Santos

As macros de maior importância estão na tabela seguinte, e que mostra qual o

procedimento indicado para ter um sistema que responda às necessidades das aplicações

que se pretendem desenvolver.

Macro Configuração do OpenRISC

OR1200_ASIC Distingue se o suporte de desenvolvimento é um ASIC ou FPGA.

OR1200_NO_DC Se estiver definida faz com que a cache de dados não seja implementada.

OR1200_NO_IC Se estiver definida faz com que a cache de instruções não seja implementada.

OR1200_NO_DMMU Se estiver definida, a MMU para dados não está presente no sistema

OR1200_NO_IMMU Se estiver definida, a MMU para instruções não está presente no sistema

OR1200_IC_1W_4KB Define o tamanho da cache de instruções para 4KB.

OR1200_DC_1W_4KB Define o tamanho da cache de dados para 4KB.

OR1200_IC_1W_8KB Define o tamanho da cache de instruções para 8KB.

OR1200_DC_1W_8KB Define o tamanho da cache de dados para 8KB.

OR1200_BIST Define se a memória incorporada tem auto-teste incorporado

OR1200_PM_IMPLEMENTED Define se a Unidade de tratamento de potência está presente no sistema.

OR1200_DU_IMPLEMENTED Define se a unidade de Debug está implementada no OR1k.

OR1200_PIC_IMPLEMENTED Permite implementar ou não a unidade que controlo as interrupções.

OR1200_PIC_INTS Define qual o número de interrupções pode ser suportado no sistema

OR1200_TT_IMPLEMENTED Define se o Tick timer está ou não presente no sistema

OR1200_SB_IMPLEMENTED Define se o Store buffer está ou não presente no sistema.

OR1200_MULT_IMPLEMENTED Define se a multiplicação está presente no OpenRISC 1200

OR1200_MAC_IMPLEMENTED Define se existe a unidade MAC no Sistema

OR1200_QMEM_IMPLEMENTED Define se existe ou não memória interna no Or1k

Tabela 8: Macros e respectiva interferência no sistema

Page 42: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 41

Pedro Mota | Pedro Santos

Aqui estão referidas as macros que são de facto aquelas que permitem a presença

dos blocos que constituem o top-level do OpenRISC 1200. No entanto, para cada um dos

blocos principais que estas macros controlam, existem outras macros que para o bloco

referido, quando implementado fazem a sua configuração

As definições relativas aos registos especiais e para os bits que os compõem,

também estão presentes neste ficheiro. Consulte-se o registo UPR que, por exemplo, revela

que unidades estão presentes através do valor para cada um dos seus bits.

A configuração das caches é feita também recorrendo a estas macros que tratam das

tags sempre presentes nestas unidades. O tratamento da memória virtual, quer para dados

quer para instruções, também tem a sua configuração presente neste ficheiro.

Para as restantes unidades que se evidenciam no Or1k, existem registos associados

que devem ser configurados, e é aqui que deve ser feita esta mesma operação.

Assim, o ficheiro OR1200_defines.v deve ser estudado com detalhe de modo a que

o sistema esteja de acordo com as funcionalidades pretendidas.

4.2.1 CPU Core top-level

Nesta secção pretende-se fazer uma caracterização para o RTL do processador, quer

através dos módulos que o constituem, como pela funcionalidade apresentada por cada um

destes.

Para proceder à extracção destes mesmos resultados foi usada a ferramenta de

síntese disponível no ambiente integrado ISE, para a FPGA XCV600.

Foi criado então um projecto com a configuração das FPGA correcta, XCV600,

obtendo-se uma hierarquia que mostrava as dependências entre módulos.

Neste momento, devem ser apresentados os tamanhos que cada um dos módulos

ocupa na XCV600 FPGA, incorporada na plataforma física de desenvolvimento. O

esquema revela a hierarquia que está associada ao top-level do CPU core, com o tamanho

descrito em slices para cada um dos sub-módulos.

Os resultados apresentados foram obtidos, realizando optimização em área e com

esforço elevado. Nessas condições, o tempo associado à síntese é mais elevado, ocupando

a maior parte dos recursos do computador.

No diagrama seguinte estão visíveis os módulos e respectivas dimensões em slices

ocupadas.

Page 43: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 42

Pedro Mota | Pedro Santos

Na tabela que lhe segue estão os módulos nucleares presentes na estrutura do Core,

fazendo-se a correspondência ao ficheiro onde estes se encontram definidos e a

funcionalidade desempenhada no Core.

Consegue-se então caracterizar o Core de acordo com estes mesmos procedimentos,

o que torna muito mais fácil a visão das várias unidades que estão presentes, assim como a

estrutura e hierarquia.

Figura 11: Esquema que representa o Core do CPU

Módulo ficheiro Função implementada no CPU CORE

OR1200_ALU or1200_alu Unidade Aritmética e lógica presente no CPU

OR1200_GENPC or1200_genpc Bloco associado ao fetch das instruções. Program counter e interface com a cache de instruções.

Page 44: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 43

Pedro Mota | Pedro Santos

OR1200_IF or1200_if Bloco associado ao fetch das instruções. Program counter e interface com a cache de instruções.

OR1200_CTRL or1200_ctrl Usado para efectuar a descodificação das instruções. Possui ainda lógica de controlo

OR1200_WBMUX or1200_wbmux CPU's write-back stage of the pipeline

OR1200_GENPC or1200_genpc Program Counter. Interface com a cache de dados

OR1200_RF or1200_rf Bloco que instancia as memórias usados para a transferência de dados entre registos e CPU

OR1200_MULT_MAC or1200_mult_mac Unidade que está associada à ALU. Implementa a multiplicação e a operação de MAC

OR1200_LSU or1200_lsu Interface entre o CPU e a cache de dados

OR1200_FREEZE or1200_freeze Trata de todas as paragens e “freezes” que ocorrem no CPU

OR1200_EXCEPT or1200_except Módulo que trata de todo as excepções que possam ocorrer no interior do CPU

OR1200_OPERANDMUXES or1200_operandmuxes Multiplexer para dois operandos de leitura do ficheiro de registo

OR1200_CFGR or1200_cfgr Módulo que realiza a configuração dos diversos registos (VR, UPR)

OR1200_RFRAM_GENERIC Or1200_rfram_generic Memória genérica usada no register file para guardar os GPRS

Tabela 9: Módulos presentes no CPU Core, correspondência com ficheiro e respectiva funcionalidade

Page 45: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 44

Pedro Mota | Pedro Santos

4.2.2 Slices associadas ao CPU Core

O top-level do CPU, fica definido com base nos parâmetros anteriores, sabendo-se

que, caso se pretenda implementar simplesmente o Core num dispositivo como a XCV600,

são necessárias 3237 slices.

Os resultados indicados direccionam-se para optimização em área, uma vez que a

capacidade desta FPGA é de cerca de 7000 slices. Caso se adicionem módulos extra para

fazer a comunicação com unidades externas e tornar este sistema mais dinâmico, o espaço

disponível pode constituir uma séria restrição.

Será bom referir que o esquema que resulta da síntese e que revela as entradas e

saídas do top-level deve ser observado com especial atenção, porque é útil para

compreender as interligações do CPU com os diferentes blocos.

Este esquema foi obtido após a realização da síntese física para a XCV600, que é o

dispositivo de interesse encontra-se no Anexo 4.

4.2.3 Top-level do OPENRISC 1200

Após se ter efectuado a caracterização do CPU core, é essencial construir um top-

level que assemble o CPU com as restantes unidades que permitem fazer um interface com

um sistema externo.

Como foi dito, na secção introdutória relativa ao RTL, o top-level do Or1k pode

ser configurado mediante as necessidades de um determinado sistema.

No entanto devemos ter acesso ao espaço que a estrutura do sistema com as

features que se consideram de maior relevância. A forma mais simples de representar essa

informação será apresentar a hierarquia e respectivos valores de slices ocupados por cada

um dos módulos.

Page 46: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 45

Pedro Mota | Pedro Santos

Figura 12: Organização do top-level do Or1k (slices ocupadas por cada módulo)

Além de ser apresentada este mesmo esquema, irá divulgar-se uma tabela que à

semelhança do que foi feito para o CPU Core contém as informações sobre os módulos,

qual o ficheiro correspondente e qual a função desempenhado no sistema. Apenas

considerar-se-ão os módulos nucleares.

Módulo ficheiro Função implementada no

CORE do OR1K

OR1200_iwb_biu OR1200_iwb_biu Interface wishbone para as

instruções no Core

OR1200_wb_biu OR1200_wb_biu Interface wishbone para dados.

OR1200_immu_top OR1200_immu_top Unidade de controlo de memória

virtual para instruções

OR1200_dmmu_top or1200_ctrl Unidade de controlo de memória

virtual para dados

OR1200_IC_TOP OR1200_IC_TOP Cache do Core para instruções.

OR1200_DC_TOP OR1200_DC_TOP Cache do Core para dados. Os sub-

módulos incluem memória para tag.

OR1200_RF or1200_rf Bloco que instancia as memórias

usados para a transferência de dados

Or1k Top-level12121 slices

QMEM (8KB)

3637slices

Inst Cache(4kb)

2146 slices

Data Cache (4kb)

2473 slices

Power Management

7 slices

Debug Unit

40 slices

Store Buffer

273 slices

PIC42 slices

Inst Wishboneinterface

90 slices

Data wishbone interface

44 slices

IMMU

150 slices

IMMU TABLE

150 slices

Tick-Timer9 slices

RAM 64x21

114 slices

Tag Cache282 slices

RAM 64x1468 slices

DMMU198 slices

RAM 64x1468 slices

RAM 64x24 103 slices

DMMU TABLE161 slices

Cache Ram ( 4KB)

1726 slices

Tag ram98 slices

Dc ram 4KB1726 Slices

Inst Tag

282 slices

Tag ram 98 slices

CPU CORE3237 slices

Page 47: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 46

Pedro Mota | Pedro Santos

entre registos e CPU

OR1200_CPU or1200_mult_mac CPU que existe no OpenRISC1200

OR1200_SB or1200_sb Store buffer

OR1200_DU OR1200_DU Unidade que permite o debug dos

programas em tempo real.

OR1200_PIC OR1200_PIC

Módulo que atende as interrupções

que venham a ocorrer no interior do

CPU ou vindas do exterior.

OR1200_TT OR1200_TT Tick-timer do sistema. Usado para

gerar interrupções periódicas.

OR1200_PM OR1200_PM Módulo responsável pelo controlo

dinâmico da potência no Or1k

OR1200_QMEM_TOP OR1200_QMEM_TOP

Memoria interna que pode ser

embebida no Core e que é tem a

vantagem de ter acessos mais

rápidos

Tabela 10: Ficheiro e funcionalidade correspondentes para um determinado módulo do Or1k

No caso presente pretende-se implementar um codec de voz, que não exige

qualquer memória virtual. Além deste aspecto admitiremos que a unidade de debug se

encontra desactivada assim como a unidade que controla as interrupções, e tick timer .

Considere-se ainda que o sistema não tem o bloco que faz o controlo inteligente de

potência e que as caches, com os valores padrão referidos nas definições das macros estão

activadas e que a unidade de memória virtual de dados e de instruções estão incluídas no

sistema.

Neste caso também se removeu a memória interna já que esta ocupava cerca de

50 % de recursos da FPGA.

Caso se faça a implementação com a configuração descrita, o valor obtido na

síntese para o espaço – recordando que ela foi feita com optimização em área e esforço

elevado,– é de 7696 slices o que excede a capacidade máxima da XCV600.

Page 48: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 47

Pedro Mota | Pedro Santos

4.2.4 Adaptando o Or1k ao espaço disponível

A cache de dados tem uma memória de 1024x32=4KB, e a de instruções

1024x32=4KB. Com estes valores para as caches não é possível fazer a integração do

sistema na XCV600.

Para solucionar este problema, fez-se a modificação das caches para 1KB. No

entanto, a modificação da memória cache para 1KB implica que se faça a mudança das

tags que lhe estão associadas de forma coerente.

No módulo que faz a instanciação da cache e onde é invocada a memória a usar,

dc_ram, é preciso que a esta seja de 256x32 = 1kB, o que indica que em termos de linha de

endereço vão ser necessárias 8 linhas. Ou seja, é preciso ter uma memória com esse valor,

que pode ser obtida a partir do modelo 1024x32, modificando o valor de aw , que indica o

número de bits para o endereço, de 10 para 8.

É necessário ainda definir a macro OR1200_IC_1W_1KB no ficheiro

or1200_defines.v. Quando se faz a invocação da ram no ficheiro dc_ram.v deve-se

contemplar o módulo de memória com as propriedades referidas.

No entanto é preciso fazer ajustes relativos à tag que está associada à cache. Para a

memória de 4KB a configuração que existe é a seguinte:

`ifdef OR1200_IC_1W_4KB `define OR1200_ICSIZE 12 // 4096 `define OR1200_ICINDX `OR1200_ICSIZE-2 // 10 `define OR1200_ICINDXH `OR1200_ICSIZE-1 // 11 `define OR1200_ICTAGL `OR1200_ICINDXH+1 // 12 `define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS //

8 `define OR1200_ICTAG_W 21 `endif

Em primeiro lugar o tamanho da cache deve ser de 1024 o que indica a passagem

da macro OR1200_ICSIZE para 10 originando os 1024 bytes.

Relativamente ao número de bits da tag este terá de ser alterado para que fique de

acordo com o novo valor da memória.

No caso em questão, os bursts para as memórias são de 16 bytes. Para ter uma

memória de 4KB como é a que esta referida é necessário que existam 4096/16 linhas, ou

seja 256 blocos de 16 bytes por bloco.

Page 49: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 48

Pedro Mota | Pedro Santos

Para se ter o valor indicado de linhas devem ser usados 8 linhas de endereço. Ou

seja, o bit menos significativo da tag estará na posição 12, já que do 0 ao 11 estarão

ocupados pelos 4 bits que indicam o offset e pelos 8 bits que indicam qual a linha a ler da

cache, ou index.

A diferença entre os 32 bits do endereço e os 12 bits referidos dá o tamanho da tag.

O valor que é apresentado no ficheiro defines.v é de 21, pois além dos 20 bits que resultam

a partir daqui ainda é adicionado um bit para indicar a validade da tag.

Isto é visível no ficheiro dc_top.v, onde ao ser invocado o módulo dc_tag, o

tamanho da tag é [`OR1200_DCTAG_W-2:0], o que indica que esta corresponde a um

registo de 20 bits, ou seja [21-2:0] =[19:0] o que está de acordo com o valor que

apresentamos.

No entanto, repare-se que é enviada para a memória que contém as tags os dados

“.datain({dc_addr[31:`OR1200_DCTAGL], dctag_v})“, que contém os 20 bits da tag mais

um que indica a validade da mesma.

Assim, se agora o tamanho da cache é de 1024 bytes, então o bit menos

significativo da tag, admitindo bursts de 16 bytes, estará na posição 10 do endereço. Neste

caso a configuração deve ser a seguinte:

`ifdef OR1200_IC_1W_1KB `define OR1200_ICSIZE 10 // 1024 `define OR1200_ICINDX `OR1200_ICSIZE-2 // 8 `define OR1200_ICINDXH `OR1200_ICSIZE-1 // 9 `define OR1200_ICTAGL `OR1200_ICINDXH+1 // 10 `define OR1200_ICTAG `OR1200_ICSIZE-`OR1200_ICLS //

6 `define OR1200_ICTAG_W 23 `endif O ajuste da tag deve ser feito também, já que neste caso a memória é de menor

dimensão, devendo então considerar-se mais dois bits já que o índex diminui de dois bits

tendo obviamente a tag de aumentar. Neste caso a tag será de 32-4-6=22 bits sendo que o

valor do parâmetro OR1200_ICTAG_W deve incluir o bit que indica a validade de mesma.

Note-se que com esta modificação no ficheiro em que se invoca a memória

associada às tags deve ser adicionado um novo módulo ao projecto com as dimensões de

64x23, ou seja 64 registos de 23 bits cada, para estar de acordo com as definições referidas.

Para melhor compreender os efeitos em termos de espaço ocupado que esta

implementação teve, estes resultados têm de ser apresentados sob a forma de uma tabela.

Page 50: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 49

Pedro Mota | Pedro Santos

Dimensões da memória Slices Ocupadas

1024x32=4KB 1726 512x32=1KB 476

Tabela 11: Slices ocupadas por cada uma das memórias

Repare-se que com o novo tamanho para as rams usadas na cache de dados e de

instruções, tamanho total usado no Or1k é reduzido de forma significativa. Com esta

modificação o espaço total ocupado foi reduzido de 7696 slices para 4353 slices, o que já

está dentro dos limites da FPGA.

A frequência máxima de funcionamento é de 17.082 MHz.

Assim, temos neste momento o core do OR1k pronto para realizar a ligação com

elementos adicionais, como memórias ou periféricos de outro género. De forma sumária,

este modelo do Or1k apenas está implementado o Core do CPU, a cache de dados e a de

instruções.

Figura 13: Configuração do OpenRisc 1200 no seu top-level e interface com o exterior

CPU/DSP

CORE

Inst. Cache

Data Cache

Wishbone interface

Wishbone interface

Wishbone interface

Wishbone interface

Or1k top

Page 51: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 50

Pedro Mota | Pedro Santos

O top-level em termos de diagrama encontra-se no Anexo 15 Anexo 1e mostra qual

o interface do Or1k com um sistema exterior e de que modo as diversas ligações devem ser

processadas.

Agora que o RTL está sintetizado, pois é necessário saber qual a sua exigência em

termos de espaço e embora não se tenha feito a sua simulação, ficando para uma fase

posterior, devem ser apresentadas as ferramentas que nos dão acesso a uma plataforma de

desenvolvimento e teste de código produzido.

4.3 Ferramentas de desenvolvimento

Nesta secção pretende-se mostrar que ferramentas existem associadas a este mesmo

processador, a forma de as instalar, problemas que surgiram dessa mesma tarefa, forma de

utilização e revelar com um pequeno exemplo de teste como fazer o debug de programas

através do código fonte gerado.

Estes são os principais tópicos que devem ser apresentados nesta secção e que são

fundamentais para o desenvolvimento de qualquer aplicação destinada ao OpenRisc 1200.

4.3.1 Ferramentas disponíveis e funcionalidade As ferramentas que podem ser obtidas de forma livre a partir do site

http://www.opencores.org/projects/or1k/ . Incluem um compilador, um debugger que

permite realizar a depuração em tempo real e um simulador que tente modelar a

arquitectura do processador e testar a validade do código fonte produzido.

As ferramentas que até ao momento têm sido utilizadas direccionam-se para o

compilador e simulador. A última destas deve ser configurada de acordo com a

organização do sistema e deve existir coerência entre o compilador e secções que estão

evidenciadas no ficheiro de configuração do simulador.

No programa de teste essa coerência irá ser referida no sentido de mostrar de forma

clara como deve ser executado esse mesmo procedimento.

4.3.2 Instalação das ferramentas

Page 52: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 51

Pedro Mota | Pedro Santos

A instalação das ferramentas de simulação, tal como acontece com a obtenção do

código fonte para o RTL tem a possibilidade de ser obtido usando o comando cvs, ou

fazendo o download através do CvsGet.

O procedimento para o caso do CvsGet é equivalente ao que foi referido neste

documento sendo que agora que os pacotes a serem obtidos devem ser “or1k/binutils”

“or1k/gcc-3.4.2 “, “or1k/gdb-5.3” e “or1k/or1ksim”.

No caso de ser usado o comando cvs basta indicar as directorias referidas. Em

qualquer dos casos, depois de se terem estes ficheiros nas pastas respectivas é necessário

executar um conjunto de instruções para a instalação e que deve ser de acordo com uma

ordem bem determinada.

Convém salientar que no arranque deste trabalho, estava a ser usado um emulador

de Linux para Windows, Cygwin. Por essa mesma razão devem ser descritos todos os

acontecimentos relativos à utilização deste mesmo software.

De acordo com a indicação dos Opencores, a primeira das ferramentas a ser

instalada devem ser as binutils, que contêm comandos como objdump, readelf, orientados

para a arquitectura do OpenRisc, posteriormente realizar a instalação do gdb e do gcc e por

último a instalação do or1ksim, já que este vai necessitar do compilador para criar os

binários usados na simulação.

Após termos o código fonte para instalar as binutils devem ser corridas as seguintes

instruções na shell (foi feita sempre em super user….)

mkdir b-b cd b-b ../binutils/configure --target=or32-uclinux --prefix=/opt/or32-uclinux make all install export PATH=/opt/or32-uclinux/bin:$PATH cd ..

Inicialmente não se estava a conseguir realizar esta tarefa pois é necessário o

automake 1.6 e o autoconf 1.4, de modo a se proceder coma execução desta instalação.

A versão do bison e do flex para versões mais recentes pode causar também

problemas na instalação. Isto será tema após se observar o que decorreu com o cygwin.

A instalação destas “utilities” foi bem sucedida, pelo que se iniciou a do

compilador. As directivas para realizar a sua instalação são as seguintes:

mkdir b-gcc cd b-gcc ../gcc-3.4.2/configure --target=or32-uclinux --prefix=/opt/or32-uclinux \

Page 53: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 52

Pedro Mota | Pedro Santos

--local-prefix=/opt/or32-uclinux/or32-uclinux --with-gnu-as \ --with-gnu-ld --verbose --enable-languages=c make all install cd ..

Também foi possível instalar este compilador dedicado e desta vez não foram

obtidos erros.

Resta-nos ter o gdb a funcionar assim como o simulador deste processador. Para se

poder instalar o gdb os comandos a invocar na shell são:

mkdir b-gdb cd b-gdb ../gdb-5.3/configure --target=or32-uclinux make all cp gdb/gdb /opt/or32-uclinux/bin/or32-uclinux-gdb cd ..

A instalação desta ferramenta decorreu com sucesso. A instalação do simulador,

deve ser realizada através das seguintes directivas:

cd or1k/or1ksim ./configure --target=or32-uclinux --prefix=/opt/or32-uclinux make all install cd ../..

A instalação do or1ksim originou erros e por mais tentativas que se fizessem,

existiam problemas permanentes na instalação.

Experimentaram-se várias versões do automake e autoconf, analisaram-se ficheiros

associados à produção de makefiles, mas o erro permanecia.

Enviou-se um e-mail para um dos responsáveis do projecto com os logs da

configuração e da instalação, e a resposta obtida foi de que a tentativa da instalação do

simular no ambiente Cygwin não havia sido testada por ele. No entanto pela consulta de

fóruns associados, o problema relativo a esta instalação era comum a muitos dos posts

colocados sobre esse assunto.

Estando neste impasse e perdendo bastante tempo nesta secção, a solução adoptada

foi usar o sistema operativo Fedora Core 2.

Page 54: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 53

Pedro Mota | Pedro Santos

Quando se fez a instalação das ferramentas indicadas, descobriu-se na página um

ATS “automatic self test”, que testava cada uma das ferramentas, o uclinux e ainda a

uclibc, mostrando em log files os resultados dessa instalação.

Assim corremos esse script numa shell e a instalação foi automática, colocando as

ferramentas todas em funcionamento.

No decorrer do trabalho, por razão desconhecida, o acesso ao sistema operativo

indicado falhou, havendo só a hipótese de recuperar o trabalho desenvolvido até ao

momento, tendo sido necessário executar uma nova instalação do sistema operativo.

Colocou-se em funcionamento o novo sistema operativo em funcionamento, mas

pelo facto de se terem realizado alguns updates, as ferramentas correndo o script

automático estavam a falhar.

Pensando que o problema estaria no S.O. utilizado, colocou-se em funcionamento o

Debian, mas , igualmente, ocorreu insucesso.

Após a análise dos erros verificou-se que algumas das versões de software

necessárias para se avançar com a instalação, estavam demasiado avançadas.

Como exemplo temos o flex, que deve ser substituído pelo flex old. Também

existiam ferramentas que não estavam presentes e que tiveram de ser instaladas, como é o

caso do bison.

Na instalação ainda houve um erro, que invocava problemas com o malloc, mas que

depois de se ter feito uma busca no google deste erro se encontrou a solução a adoptar.

É assim essencial verificar se as versões das ferramentas do sistema suportam ou

não a instalação da GNU TOOLCHAIN, e, caso a instalação não esteja a ter sucesso,

devem ser alteradas para as versões mais antigas, que podem ser obtidas a partir do

manager de pacotes de instalação presente neste mesmo sistema operativo.

4.3.3 Produção de binários e ferramentas auxiliares

Quando se realiza a instalação do or1ksim, são gerados os binários a partir do

código fonte. Estes binários são usados no simulador, pelo que devemos ter em

consideração a forma como são gerados.

Para ter acesso às ferramentas a partir de qualquer directoria de trabalho deve ser

chamado o seguinte comando que associa o local onde se encontram as ferramentas a uma

variável de ambiente:

export PATH=/opt/or32-uclinux/bin:$PATH

Page 55: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 54

Pedro Mota | Pedro Santos

Para aceder a esta mesma informação, deve ser feita a análise do makefile que se

encontra na pasta or1ksim/testbench/ e que mostra como são gerados os binários que o

simulador usa.

O makefile é de facto extenso, e a sua análise ocupou bastante tempo, para que se

pudessem encontrar as directivas de compilação para criar os ficheiros binários.

Os ficheiros fonte têm de ser compilados com o or32-uclinux-gcc, o compilador

dedicado a esta arquitectura, mas não se deve fazer o link indicado pela flag-c e não se

deve fazer uso da standard library, -nostdlib e deve ser usada –mhard-div que é uma flag

dedicada para este mesmo processador. Para melhor compreensão deve ser consultado o

manual do gcc.

Após se ter feito a compilação de todos os ficheiros objecto deve ser feito o linking

entre estes. Para isso, tem de estar presente o ficheiro default.ld que possui a divisão das

várias secções de memória que estão associadas ao binário.

Deve ainda ser associada a libraria libsupport.a que contém funções especiais e o

objecto das excepções, – except.o – que é essencial para colocar o processador com a

sequência de boot e o tratamento de excepções habilitado.

O ficheiro except.o está presente na pasta or1ksim/testbench e foi gerado no

momento da instalação a partir do except.S, ficheiro este que está escrito em assembly e

que faz o tratamento das excepções.

É conveniente referir como é feita a organização da memória no binário que foi

produzido, para mais tarde compreender o código que foi gerado e a forma como este se

organiza.

MEMORY { except : ORIGIN = 0x00000000, LENGTH = 0x00002000 flash : ORIGIN = 0xf0000000, LENGTH = 0x10000000 ram : ORIGIN = 0x00002000, LENGTH = 0x001fe000 } SECTIONS { .text : { *(.text) *(.rodata*) _src_beg = .;

Page 56: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 55

Pedro Mota | Pedro Santos

} > flash .dummy ALIGN(0x4): { _src_beg = .; } > flash .except : AT ( ADDR (.dummy)) { _except_beg = .; *(.except) _except_end = .; } > except .data : AT ( ADDR (.dummy) + SIZEOF (.except)) { _dst_beg = .; *(.data) _dst_end = .; } > ram .bss : { *(.bss) } > ram .stack ALIGN(0x10) (NOLOAD): { *(.stack) _ram_end = .; } > ram }

Ficheiro de apoio 1: default.ld- contém as definições das diversas regiões de memória e endereços iniciais

Assim como se pode ver a parte da memória destinada a programa, flash, inicia-se

em 0xF000_0000 e tem uma dimensão de 0x1000_0000. A secção das excepções

compreende-se entre 0x0000_0000 e 0x0000_1FFF. A região de dados, ram, inicia-se em

0x0000_2000 e tem um tamanho de 0x001F_E000. Dentro da região de dados podemos

fazer a divisão em data, bss e stack.

É este ficheiro que tem ser usado para adaptar o Core ao sistema de memória que

está presente na interface. E mediante os requisitos de memória, deve ser feita a

modificação de endereços e de espaços associados para cada um dos diferentes segmentos

definidos.

Page 57: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 56

Pedro Mota | Pedro Santos

O ficheiro default.ld que se apresentou é aquele que no makefile de estudo é

utilizado para fazer o linking entre os diferentes objectos.

Para se poder mostrar de forma clara como realizar esta tarefa, apresenta-se um

simples makefile. A finalidade deste ficheiro é simplesmente testar a multiplicação.

Repare-se que no or1ksim existem vários binários que pretendem testar vários

componentes presentes no OR1k. O ficheiro fonte que estamos a usar, mul.c, encontra-se

em or1ksim/testbench servindo para produzir um binário que serve de teste no simulador.

Se os resultados obtidos no simulador, com binário gerado usando o makefile

seguinte for igual aos obtidos a partir do binário do or1ksim/testbench/, então estamos a ter

o procedimento correcto para criar esses mesmos binários para simulação.

objects=mul.o except.o CC=or32-uclinux-gcc FLAGS_2=-Wall -g -nostdlib -mhard-div FLAGS_1=-I. -I/home/pedro/tools/or1k/or1ksim/testbench/support SUPPORTLIBS=/home/pedro/tools/or1k/or1ksim/testbench/support/libsupport.a LD_FLAGS= -nostdlib $(SUPPORTLIBS) mul : $(objects) $(CC) -o mul -T.//default.ld $(LD_FLAGS) $(objects) $(LD_FLAGS) mul.o : mul.c $(CC) -c $(FLAGS_1) $(FLAGS_2) mul.c

Ficheiro de apoio 2:Makefile que permite a criação do binário a ser usado para a simulação

Como em qualquer plataforma de desenvolvimento é fundamental conhecer a forma

como é traduzido o código C em termos das instruções dedicadas para o processador,

assim como as várias secções de memória e respectivo tamanho. Por essa razão são

indicadas as ferramentas usadas, assim como o procedimento de utilização e os resultados

esperados sempre que são invocadas.

Nesse caso, podem então ser salientadas as ferramentas or32-uclinux-objdump

chamada com a flag – S de modo a misturar o código em C e as instruções que foram

geradas com o respectivo endereço.

O comando or32-uclinux-readelf com a flag–a, ao ser invocado permite que se

possam visualizar as diferentes secções em que o binário está dividido e o respectivo

endereço inicial e o tamanho da secção que lhe está associada.

Existe ainda o comando or32-uclinux-size que indica de forma sucinta os valores

em termos de espaço ocupados por cada um destes.

Page 58: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 57

Pedro Mota | Pedro Santos

Por esta mesma razão apresentar-se-á aqui os resultados da invocação destes

mesmos comandos e as próprias secções de memória que foram definidas no ficheiro

default.ld.

mul: file format elf32-or32 Disassembly of section .text: f0000000 <_reset_vector-0x100>: ... f0000100 <_reset_vector>: f0000100: 9c 40 00 00 l.addi r2,r0,0x0 f0000104: 9c 60 00 00 l.addi r3,r0,0x0 f0000108: 9c 80 00 00 l.addi r4,r0,0x0 f000010c: 9c a0 00 00 l.addi r5,r0,0x0 f0000110: 9c c0 00 00 l.addi r6,r0,0x0 f0000114: 9c e0 00 00 l.addi r7,r0,0x0 f0000118: 9d 00 00 00 l.addi r8,r0,0x0 int main () { f00006d8: 9c 21 ff d4 l.addi r1,r1,0xffffffd4 f00006dc: d4 01 10 10 l.sw 0x10(r1),r2 f00006e0: 9c 41 00 2c l.addi r2,r1,0x2c f00006e4: d4 01 48 0c l.sw 0xc(r1),r9 unsigned t1; unsigned t2; unsigned t3; printf ("%08x\n", MACRC); f00006e8: 04 00 00 9b l.jal f0000954 <_macrc> f00006ec: 15 00 00 00 l.nop 0x0 f00006f0: d4 01 58 04 l.sw 0x4(r1),r11 f00006f4: 18 60 f0 00 l.movhi r3,0xf000 f00006f8: a8 63 10 94 l.ori r3,r3,0x1094 f00006fc: d4 01 18 00 l.sw 0x0(r1),r3 f0000700: 04 00 00 bc l.jal f00009f0 <_printf> f0000704: 15 00 00 00 l.nop 0x0 MAC (888888887, 0x87654321); f0000708: 18 80 34 fb l.movhi r4,0x34fb f000070c: a8 84 5e 37 l.ori r4,r4,0x5e37 f0000710: 18 60 87 65 l.movhi r3,0x8765 f0000714: a8 63 43 21 l.ori r3,r3,0x4321 f0000718: c4 04 18 01 l.mac r4,r3 Disassembly of section .except: 00000000 <_except_beg>: 0: 9c 21 ff 88 l.addi r1,r1,0xffffff88 4: d4 01 48 1c l.sw 0x1c(r1),r9 8: d4 01 50 20 l.sw 0x20(r1),r10 c: 19 20 f0 00 l.movhi r9,0xf000 10: a9 29 02 a8 l.ori r9,r9,0x2a8 14: 19 40 00 00 l.movhi r10,0x0 18: a9 4a 20 00 l.ori r10,r10,0x2000 1c: 44 00 48 00 l.jr r9

Page 59: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 58

Pedro Mota | Pedro Santos

20: 15 00 00 00 l.nop 0x0 00000024 <_buserr_vector_end>: 24: 9c 21 ff 88 l.addi r1,r1,0xffffff88 28: d4 01 48 1c l.sw 0x1c(r1),r9 2c: d4 01 50 20 l.sw 0x20(r1),r10 30: 19 20 f0 00 l.movhi r9,0xf000 34: a9 29 02 a8 l.ori r9,r9,0x2a8 38: 19 40 00 00 l.movhi r10,0x0 3c: a9 4a 20 04 l.ori r10,r10,0x2004 40: 44 00 48 00 l.jr r9 44: 15 00 00 00 l.nop 0x0

Figura 14: Resultados obtidos ao ser invocado o or32-uclinux-objdump –S mul ELF Header: Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, big endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: OpenRISC Version: 0x1 Entry point address: 0xf0000000 Start of program headers: 52 (bytes into file) Start of section headers: 46920 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 4 Size of section headers: 40 (bytes) Number of section headers: 17 Section header string table index: 14 Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS f0000000 004000 0010ce 00 AX 0 0 4 [ 2] .rel.text REL 00000000 00c518 000000 08 15 1 4 [ 3] .dummy PROGBITS f00010d0 008034 000000 00 W 0 0 1 [ 4] .except PROGBITS 00000000 006000 0001d4 00 AX 0 0 1 [ 5] .rel.except REL 00000000 00c518 000000 08 15 4 4 [ 6] .data PROGBITS 00002000 008000 000034 00 WA 0 0 4 [ 7] .rel.data REL 00000000 00c518 000000 08 15 6 4 [ 8] .bss NOBITS 00002040 002040 000100 00 WA 0 0 16 [ 9] .stack PROGBITS 00002140 008034 001000 00 0 0 1

Page 60: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 59

Pedro Mota | Pedro Santos

[10] .stab PROGBITS 00000000 009034 001260 0c 12 0 4 [11] .rel.stab REL 00000000 00c518 000000 08 15 a 4 [12] .stabstr STRTAB 00000000 00a294 001414 00 0 0 1 [13] .comment PROGBITS 00000000 00b6a8 000036 00 0 0 1 [14] .shstrtab STRTAB 00000000 00b6de 00006a 00 0 0 1 [15] .symtab SYMTAB 00000000 00b9f0 000710 10 16 49 4 [16] .strtab STRTAB 00000000 00c100 000416 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific) Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x02040 0x02140 RW 0x2000 LOAD 0x004000 0xf0000000 0xf0000000 0x010ce 0x010ce R E 0x2000 LOAD 0x006000 0x00000000 0xf00010d0 0x001d4 0x001d4 R E 0x2000 LOAD 0x008000 0x00002000 0xf00012a4 0x00034 0x00034 RW 0x2000 Section to Segment mapping: Segment Sections... 00 .except .data .bss 01 .text 02 .except 03 .data There is no dynamic segment in this file. There are no relocations in this file. There are no unwind sections in this file. Symbol table '.symtab' contains 113 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS except.S 2: 00000000 0 FILE LOCAL DEFAULT ABS board.h 3: 00000000 0 FILE LOCAL DEFAULT ABS except.S 4: 00000000 0 FILE LOCAL DEFAULT ABS support/spr_defs.h 5: 00000000 0 FILE LOCAL DEFAULT ABS except.S 6: 00000000 0 FILE LOCAL DEFAULT ABS <command line> 7: 00000000 0 FILE LOCAL DEFAULT ABS <built-in> 8: 00000000 0 FILE LOCAL DEFAULT ABS except.S 9: f0000000 0 SECTION LOCAL DEFAULT 1 10: 00002000 0 SECTION LOCAL DEFAULT 6 11: 00002040 0 SECTION LOCAL DEFAULT 8 12: 00002140 0 SECTION LOCAL DEFAULT 9 13: 00003140 0 NOTYPE LOCAL DEFAULT 9 _stack 14: 00000000 0 SECTION LOCAL DEFAULT 4

Page 61: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 60

Pedro Mota | Pedro Santos

15: 00000000 0 NOTYPE LOCAL DEFAULT 4 _buserr_vector 16: f00002a8 0 NOTYPE LOCAL DEFAULT 1 store_regs 17: 00000024 0 NOTYPE LOCAL DEFAULT 4 _buserr_vector_end 18: 00000024 0 NOTYPE LOCAL DEFAULT 4 _dpfault_vector 19: 00000048 0 NOTYPE LOCAL DEFAULT 4 _dpfault_vector_end 20: 00000048 0 NOTYPE LOCAL DEFAULT 4 _ipfault_vector 21: 0000006c 0 NOTYPE LOCAL DEFAULT 4 _ipfault_vector_end 22: 0000006c 0 NOTYPE LOCAL DEFAULT 4 _lpint_vector 23: 00000090 0 NOTYPE LOCAL DEFAULT 4 _lpint_vector_end 24: 00000090 0 NOTYPE LOCAL DEFAULT 4 _align_vector 25: 000000b4 0 NOTYPE LOCAL DEFAULT 4 _align_vector_end 26: 000000b4 0 NOTYPE LOCAL DEFAULT 4 _illinsn_vector 27: 000000d8 0 NOTYPE LOCAL DEFAULT 4 _illinsn_vector_end 28: 000000d8 0 NOTYPE LOCAL DEFAULT 4 _hpint_vector 29: 000000fc 0 NOTYPE LOCAL DEFAULT 4 _hpint_vector_end 30: 000000fc 0 NOTYPE LOCAL DEFAULT 4 _dtlbmiss_vector 31: 00000120 0 NOTYPE LOCAL DEFAULT 4

Figura 15:Resultados obtidos ao ser invocado o or32-uclinux-readelf –a mul

Ainda exista a possibilidade de se visualizar o hexdump da secção pretendida. Para

isso deve ser invocado o comando or32-uclinux-readelf –x 1 mul ( representa o número de

secção)

Hex dump of section '.text': 0xf0000000 00000000 00000000 00000000 00000000 ................ 0xf0000010 00000000 00000000 00000000 00000000 ................ 0xf0000020 00000000 00000000 00000000 00000000 ................ 0xf0000030 00000000 00000000 00000000 00000000 ................ 0xf0000040 00000000 00000000 00000000 00000000 ................ 0xf0000050 00000000 00000000 00000000 00000000 ................ 0xf0000060 00000000 00000000 00000000 00000000 ................ 0xf0000070 00000000 00000000 00000000 00000000 ................ 0xf0000080 00000000 00000000 00000000 00000000 ................ 0xf0000090 00000000 00000000 00000000 00000000 ................ 0xf00000a0 00000000 00000000 00000000 00000000 ................ 0xf00000b0 00000000 00000000 00000000 00000000 ................ 0xf00000c0 00000000 00000000 00000000 00000000 ................ 0xf00000d0 00000000 00000000 00000000 00000000 ................ 0xf00000e0 00000000 00000000 00000000 00000000 ................ 0xf00000f0 00000000 00000000 00000000 00000000 ................ 0xf0000100 9c400000 9c600000 9c800000 9ca00000 .@...`.......... 0xf0000110 9cc00000 9ce00000 9d000000 9d200000 ............. .. 0xf0000120 9d400000 9d600000 9d800000 9da00000 .@...`.......... 0xf0000130 9dc00000 9de00000 9e000000 9e200000 ............. .. 0xf0000140 9e400000 9e600000 9e800000 9ea00000 .@...`.......... 0xf0000150 9ec00000 9ee00000 9f000000 9f200000 ............. .. 0xf0000160 9f400000 9f600000 9f800000 9fa00000 .@...`.......... 0xf0000170 9fc00000 9fe00000 1860f000 a8630188 .........`...c.. 0xf0000180 44001800 15000000 0400002b 15000000 D..........+.... 0xf0000190 18200000 a8213140 1860f000 a86310d0 . ...!1@.`...c.. Continua…..

Figura 16: Resultados da execução do comando or32-uclinux-readelf –x 1 mul

Page 62: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 61

Pedro Mota | Pedro Santos

text data bss dec hex filename 0x12a2 0x34 0x100 5078 13d6 mul

Figura 17:Resultados obtidos ao ser invocado o or32-uclinux-size -- radix=16 mul ( formatação em hexadecimal)

Agora que se revelaram o método para a produção dos binários usados para a

simulação, resta demonstrar que configuração deve estar presente no simulador, e como

esta deve ser feita de forma coerente com o ficheiro default.ld.

Tem que existir concordância entre estes caso contrário o simulador não funcionará.

4.3.4 Simulação dos binários produzidos

Na fase inicial de teste do simulador com os binários que haviam sido produzido, o

simulador não executava nada do pretendido. Isto relacionava-se com o facto de não se

estar a fazer o linking com o ficheiro das excepções, que contém a inicialização do sistema

e o atendimento das excepções.

Após se ter feito essa operação já com o objecto das excepções considerado, o

simulador estava a produzir os resultados esperados para o código que se tinha escrito.

O simulador em questão é invocado através de or32-uclinux-sim, sendo preciso

para que este corra com determinadas configurações que exista o ficheiro sim.cfg, no

directório em que este se encontra. Caso não exista esse ficheiro, ele irá correr com um

ficheiro padrão que não corresponde à configuração que queremos para um determinado

sistema.

Para que o simulador corresse quando o invocávamos era preciso que o fizéssemos

com permissões de root.

Existem dois modos para ser invocado este simulador, um modo em que este

executa continuamente e outro em que pode estar em funcionamento interactivo.

Para que o segundo modo esteja disponível deve ser chamado com a flag –i. Assim

para correr o simulador deve ser chamado o comando da seguinte forma or32-uclinux-sim

sim.cfg –i mul.

Page 63: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 62

Pedro Mota | Pedro Santos

Relativamente ao simulador no modo interactivo, apresenta-se em baixo um

“snapshot” do mesmo. Irá referir-se ainda um conjunto de comandos que pode ser usado

para facilitar o debug de programas e que auxiliam na tarefa árdua da descoberta da causa

do erro.

Reading script file from 'sim.cfg'... Verbose on, simdebug off, interactive prompt on Machine initialization... Clock cycle: 100ns Data cache present. Insn cache tag present. BPB simulation off. BTIC simulation off. Building automata... done, num uncovered: 0/212. Parsing operands data... done. loadcode: filename main startaddr=00000000 virtphy_transl=00000000 Not COFF file format ELF type: 0x0002 ELF machine: 0x8472 ELF version: 0x00000001 ELF sec = 17 Section: .text, vaddr: 0xf0000000, paddr: 0xf0000000, offset: 0x000000c0, size: 0x000033ac Section: .except, vaddr: 0x00000000, paddr: 0xf00033ac, offset: 0x0000346c, size: 0x000001d4 Section: .data, vaddr: 0x00002000, paddr: 0xf0003580, offset: 0x00003640, size: 0x0000003c WARNING: dependstats stats must be enabled to do history analisis. WARNING: Unable to open RX file stream. Resetting memory controller. Resetting Tick Timer. Resetting Power Management. Resetting PIC. Starting at 0x00000000 Exception 0x00000100 (Reset) at 0x00000000, EA: 0x00000000, ppc: 0x00000000, npc: 0x00000004, dpc: 0x00000000, cycles 0, #0 (sim) t 00000104: : 9c600000 l.addi r3,r0,0x0 (executed) [cycle 20, #2] 00000108: : 9c800000 l.addi r4,r0,0x0 (next insn) GPR00: 00000000 GPR01: 00000000 GPR02: 00000000 GPR03: 00000000 GPR04: 00000000 GPR05: 00000000 GPR06: 00000000 GPR07: 00000000 GPR08: 00000000 GPR09: 00000000 GPR10: 00000000 GPR11: 00000000 GPR12: 00000000 GPR13: 00000000 GPR14: 00000000 GPR15: 00000000 GPR16: 00000000 GPR17: 00000000 GPR18: 00000000 GPR19: 00000000 GPR20: 00000000 GPR21: 00000000 GPR22: 00000000 GPR23: 00000000 GPR24: 00000000 GPR25: 00000000 GPR26: 00000000 GPR27: 00000000 GPR28: 00000000 GPR29: 00000000 GPR30: 00000000 GPR31: 00000000 flag: 0 (sim) Ficheiro de apoio 3: Aspecto do simulador. São evidenciados os registos e as instruções do processador.

Page 64: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 63

Pedro Mota | Pedro Santos

Os comandos principais que podem ser usados para realizar debug são os que estão

na tabela. Coloca-se um exemplo da sua utilização e a sua funcionalidade dos mesmos.

Comando Funcionalidade no simulador

q Abandonar o simulador

r Mostra os registos GPRS

t Executa a próxima instrução

run ex; run 10; run 10 hush

Executa, de acordo com o exemplo, as 10

próximas instruções. No primeiro caso faz o

display dos registos para o ecrã em todas as

instruções executadas e no segundo caso já

não o faz.

pr <r> <value> ex: pr 20 12 Coloca o registo 20 com o valor 12

dm endereço_inicial endereço_final

Ex: dm 0x0000_2000 0x0000_4000

Mostra o conteúdo da posição de memória

0x0000_2000 à posição 0x0000_4000

pm endereço valor pm 0x0000_1234 12 Coloca na posição de memória 0x0000_1234 o valor 12

pc valor

Coloca o programa counter como valor indicado. Isto significa que a próxima instrução a ser executada será aquela que está no endereço indicado pelo valor que foi carregado para este mesmo registo

info

Permite ter acesso aos valores que os diferentes registos especiais têm definidos e observar se por exemplo alguma flag foi ou não activa ou que unidades estão presentes.

cm endereço_inicial endereço_final size cm 0x0000_1234 0x0000_4567 0xf

Copia um bloco com o tamanho de 0xf que se inicia no endereço 0x0000_1234, para outra zona de memória iniciando a cópia a partir de 0x0000_4567

break endereço (ou label) break 0xF000_1FAB

break teste

Coloca quando se está a realizar o debug um breakpoint no endereço indicado, ou numa label associada a um determinado endereço.

breaks Mostra que breakpoints é que estão presentes na simulação.

reset Executa o reset do simulador, voltando-se ao início da memória do programa e com os registos limpos.

Stat Permite visualizar as estatísticas associadas

Page 65: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 64

Pedro Mota | Pedro Santos

às instruções que foram executadas

help Permite ter acesso à ajuda incorporada no simulador.

hist Permite ver que instruções foram executadas até ao momento actual.

Tabela 12:Comandos disponíveis no simulador e respectiva funcionalidade

Para ter o simulador configurado de acordo com o pretendido é preciso ter o

ficheiro sim.cfg de acordo.

Na parte inicial deste mesmo ficheiro de configuração estão presentes os

dispositivos de memória que têm de estar de acordo com default.ld quer em termos de

endereços iniciais quer em termos de espaço.

Assim, se observarmos o ficheiro default.ld e o segmento inicial do sim.cfg, que

será mostrado seguidamente veremos que estes concordam.

/* MEMORY SECTION This section specifies how the memory is generated and the blocks it consists of. type = random/unknown/pattern Specifies the initial memory values. 'random' generates random memory using seed 'random_seed'. 'pattern' fills memory with 'pattern'. 'unknown' does not specify how memory should be generated, leaving the memory in a undefined state. This is the fastest option. random_seed = <value> random seed for randomizer, used if type = 'random'. pattern = <value> pattern to fill memory, used if type = 'pattern'. nmemories = <value> number of memory instances connected instance specific: baseaddr = <hex_value> memory start address size = <hex_value> memory size name = "<string>" memory block name ce = <value> chip enable index of the memory instance delayr = <value>

Page 66: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 65

Pedro Mota | Pedro Santos

cycles, required for read access, -1 if instance does not support reading delayw = <value> cycles, required for write access, -1 if instance does not support writing log = "<filename>" filename, where to log memory accesses to, no log, if log command is not specified */ section memory /*random_seed = 12345 type = random*/ pattern = 0x00 type = unknown /* Fastest */ nmemories =2 device 0 name = "FLASH" ce = 0 baseaddr = 0xf0000000 size = 0x00800000 delayr = 10 delayw = 2 enddevice device 1 name = "RAM" ce = 1 baseaddr = 0x00000000 size = 0x00210000 delayr = 1 delayw = 2 enddevice

Figura 18: Configuração da memória usada no simulador

Aqui estão definidos dois dispositivos de memória, sendo que o endereço inicial da

“flash” e o que existe no ficheiro default.ld são os mesmos e o espaço que aqui está

definido satisfaz aquele que é definido no ficheiro default.ld.

O somatório da memória dedicada para as excepções e aquela que está direccionada

para bss, stack e dados está perfeitamente contido no espaço indicado e o valor inicial para

o endereço também se encontram em concordância.

É necessário referir as várias secções que estão presentes neste ficheiro, sendo que

cada um dos componentes instanciados no sim.cfg tem informação detalhada constituindo

assim a única documentação que existe para o funcionamento deste simulador.

Page 67: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 66

Pedro Mota | Pedro Santos

Neste documento não é pretendido fazer uma descrição exaustiva sobre esse

aspecto mas referir que elementos existem e se estão ou não habilitados na configuração

presente.

SECÇÃO Descrição/Activação

MEMORY Define como a memória é gerada e em que blocos está dividida. IMMU Secção que trata da configuração da Immu. No caso presente está inactiva.

DMMU Secção que trata da configuração da Dmmu. No caso presente está inactiva.

IC Secção que faz a configuração da cache de instruções e dos seus parâmetros como tamanho e numero de “sets” presentes. Activa na configuração presente.

DC Secção que faz a configuração da cache de dados e dos seus parâmetros como tamanho e numero de “sets” presentes. Activa na configuração presente.

SIM

Nesta secção é configurado o comportamento do simulador relativamente à profundidade das mensagens de debug, activação da criação de histórico e estatísticas de execução, assim como se inibe a geração de logs relativos à execução das instruções.

VAPI Secção que faz a configuração da Verification API, usada para verificação avançada do Core. Esta desabilitada na configuração actual.

CPU Esta secção permite definir vários parâmetros para o CPU, como a versão eo registo UPR.

PM Permite activar ou não a unidade que faz o controlo de potência. No presente caso esta encontra-se desactivada.

BPB Nesta secção controlam-se os parâmetros relativos à previsão dos saltos. Agora encontra-se desactivada.

DEBUG Secção destinada configurar o comportamento da unidade de debug que está incorporada no Or1k.

MC Permite realizar a configuração do controlador de memória, como o endereço base. No momento presente este encontra-se activo.

UART Permite a configuração da UART, como o seu endereço no espaço de memória, o tipo de UART que se está a usar e ainda algumas configurações temporais. Está desactivada para a presente configuração.

DMA Permite a configuração do controlador de acesso a memória, como o endereço ocupado. Não está activo.

ETHERNET

Permite a configuração da ethernet no sistema. Mais uma vez está indicado o seu endereço no espaço total. Não esta activada. Atenção apenas foi possível arrancar com o simulador desactivando a ethernet que vinha activada no ficheiro inicial.

GPIO Faz a configuração dos general purpose input outputs. Endereço base e o número da interrupção. Não se encontra presente na configuração actual.

VGA Permite que se configure um controlador de VGA ou de LCD. Não está

Page 68: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 67

Pedro Mota | Pedro Santos

activada na configuração pretendida.

TICK TIMER Secção que trata da configuração do gerador de ticks e qual a interrupção que está associada ao mesmo. Está desabilitado no presente momento.

FRAME BUFFER

Secção que faz a configuração do frame buffer. Mais uma vez o endereço a que este responde também é um dos parâmetros a configurar. Está inactivo.

KBD Secção que realiza a configuração do teclado. O endereço e o número da interrupção têm de ser controlados.

ATA Faz a configuração do controlador ARA/ATAPI. O endereço é configurável assim como o número da interrupção. Permite simular um disco, ou usar o disco do sistema local. Não se encontra activado.

CUC Configura a unidade de compilação do OpenRisc. Encontra-se desactivada na presente situação.

Tabela 13: Secções que constituem o sim.cfg e que podem sofrer alterações

Após ter-se revelado estes detalhes sobre o ficheiro de configuração, é então

esclarecedor mostrar o simulador a correr em qualquer um dos modos que foram referidos

e observar os resultados.

No modo contínuo apenas teremos acesso aos valores finais, obtidos por mensagens

na consola, enquanto que no segundo caso poderemos ir observando a evolução do

programa em termos de registos e de instruções e valores que estão na memória.

Apresentamos aqui o resultado da simulação deste mesmo binário na figura

seguinte, tendo como base a função que estamos a tentar testar.

Exception 0x00000100 (Reset) at 0x00000000, EA: 0x00000000, ppc: 0x00000000, npc: 0x00000004, dpc: 0x00000000, cycles 0, #0 [34fb5e37,87654321] (e70a2588,cac28a17) [34fb5e37,87654321] (e70a2588,cac28a17) [70a2588c,00000003] (00000001,51e709a4) [70a2588c,00000005] (00000003,8512c460) [70a2588c,00000007] (00000006,99833034) . . . . . . [8f504efc,00000071] (3d5e252e,41e3c5e8) [9e54b724,000003e5] (3d5e23b1,e1d1051c) report(0xdeaddead); exit(00000000) @reset : cycles 0, insn #0 @exit : cycles 173401, insn #16125 diff : cycles 173401, insn #16125

Figura 19:Resultado da execução do programa de teste mul

Page 69: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 68

Pedro Mota | Pedro Santos

O programa correu sem qualquer problema obtendo-se os resultados que estão a

observar na figura que se encontra acima. O que aqui está a ser mostrado é a multiplicação

de dois valores, na coluna da esquerda, e o resultado do acumulador após esta operação.

Está apresentada a parte mais significativa MACHI e a menos significativa MACLO.

Na secção seguinte existe um conjunto de funções que se pensa importante

destacar e que estão incluídas na libraria libsupport.a. Convém referir que a informação

disponibilizada pelo simulador inclui o número de instruções executadas e ciclos

necessários. A diferença entre eles prende-se com os valores usados no delay para leitura e

escrita nas memórias.

4.3.5 Funções de interesse presentes na libraria usada no linking

Nesta libraria encontram-se algumas das funções que auxiliam o debug. Estas

funções podem ser encontradas na directoria “or1k/or1ksim/testbench/support”, nos

ficheiros support.c e support.h.

Das que lá se encontram a função printf era a de maior interesse. Esta foi

implementada directamente para este simulador, mas nos testes que foram executados não

produziu qualquer resultado, o que de facto é estranho.

Foram várias as tentativas com programas simples, que mesmo um elementar

printf, como sendo o conteúdo de todo o ficheiro, não produzia o que tanto era esperado.

Por este motivo as funções report, mfspr, mtspr são de especial interesse.

A função report permite que o valor de uma determinada variável seja enviado para

o écran como report ( variável).

As outras duas funções permitem fazer a leitura e a escrita de registos especiais

definidos em spr_defs.h.

Conjugando a função report e a função mfspr, temos a possibilidade de realizar a

leitura e colocar o valor no ecrã desse mesmo registo, o que é uma forma de debug quer

para estes registos, (flags accionadas p ex.) ou para variáveis que estão a ser usadas no

programa.

Existem outras funções como é o caso da de exit, start_timer, read_timer que são

úteis. A função exit permite terminar a execução de um determinado programa, retornando

o valor de erro que foi gerado. As restantes tal como o seu nome indica, associam-se com o

arranque e a leitura de temporizadores.

Page 70: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 69

Pedro Mota | Pedro Santos

Coloca-se aqui um exemplo do uso das funções de report, e de escrita e de leitura

de valores especiais e o respectivo resultado da execução das mesmas.

#include "spr_defs.h" #include "support.h" int main (void) { unsigned long x; mtspr(SPR_MACHI, 0x55); x = mfspr (SPR_MACHI); report (x); exit (5); }

Ficheiro de apoio 4: Ficheiro que mostra a potencialidade das funções referidas

Section: .text, vaddr: 0xf0000000, paddr: 0xf0000000, offset: 0x00004000, size: 0x00000b14 Section: .except, vaddr: 0x00000000, paddr: 0xf0000b14, offset: 0x00006000, size: 0x000001d4 Section: .data, vaddr: 0x00002000, paddr: 0xf0000ce8, offset: 0x00008000, size: 0x00000034 WARNING: dependstats stats must be enabled to do history analisis. setting status register BSY 0x80 WARNING: Unable to open RX file stream. UART at 0x90000000 Resetting memory controller. Resetting Tick Timer. Resetting Power Management. Resetting PIC. Starting at 0x00000000 Exception 0x00000100 (Reset) at 0x00000000, EA: 0x00000000, ppc: 0x00000000, npc: 0x00000004, dpc: 0x00000000, cycles 0,#0 report(0x00000055); exit(00000005) @reset : cycles 0, insn #0 @exit : cycles 16398, insn #1479 diff : cycles 16398, insn #1479

Figura 20: Resultado da simulação do ficheiro representado acima

Como é visualizado, a utilidade destas funções é fundamental para diagnosticar

qualquer erro que esteja a acontecer e a partir dá fazer a correcção necessária.

Page 71: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 70

Pedro Mota | Pedro Santos

5 Profiling e análise do codec AMR

5.1 Introdução

Nesta fase do trabalho procedeu-se à realização da análise e profiling do codec

AMR. A análise concentrou-se no AMR a funcionar no seu modo de maior débito:

12.2 kbit/s.

A norma define, na sua versão em código C, uma série de ‘contadores’ que vão

sendo incrementados de forma a se conseguir medir o peso computacional do codec. Estes

‘contadores’ estão associados a funções que definem operações básicas do codec como

adições subtracções, multiplicações, etc. Desta forma é-nos possível estimar o peso

computacional em WMOPS (weighted million operations per second). Regra geral, é

necessário multiplicar-se este valor por 1.2 a 1.5 para se obter um valor em MIPS (million

instructions per second).

5.2 Análise ao estilo de programação definido pela norma

Fazendo uma análise visual ao código encontra-se rapidamente um conjunto de

instruções, ditas básicas, que são responsáveis por todas as operações aritméticas existentes

no código. Ou seja, ao longo de todo o código não existe uma única chamada aos

operadores do C de +, *, /, etc. exceptuando as necessárias a controlar ciclos (for, while).

for (i = 5; i > 0; i--) { f1[i] = L_add (f1[i], f1[i - 1]); move32 (); /* f1[i] += f1[i-1]; */ f2[i] = L_sub (f2[i], f2[i - 1]); move32 (); /* f2[i] -= f2[i-1]; */ } a[0] = 4096; move16 (); for (i = 1, j = 10; i <= 5; i++, j--) { t0 = L_add (f1[i], f2[i]); /* f1[i] + f2[i] */ a[i] = extract_l (L_shr_r (t0, 13)); move16 (); t0 = L_sub (f1[i], f2[i]); /* f1[i] - f2[i] */ a[j] = extract_l (L_shr_r (t0, 13)); move16 (); }

Este pequeno exemplo ilustra o que foi dito. Repare-se que para se para se realizar

uma soma recorre-se à função L_add e não ao operador +. Outras funções que aparecem

exaustivamente no código são as funções move16(), move32(), test(), logic16() e logic32().

Estas últimas funções encontram-se definidas no ficheiro count.c, e servem para

Page 72: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 71

Pedro Mota | Pedro Santos

incrementar um contador para se realizar o profiling do código caso se pretenda tal

operação.

Quanto à implementação dos algoritmos propriamente ditos concluiu-se que o

código já se encontra optimizado no sentido em que não existem funções que estejam

implementadas de forma não eficiente.

5.2.1 Operações básicas De seguida é apresentada uma tabela com todas as operações básicas definidas pela

norma do codec. Estas instruções podem ser encontradas nos ficheiros basic_op.h e

basicop2.c. Neste último é feita uma descrição detalhada de todas estas operações.

De notar que Word16 e Word32 significa uma variável de 16 e 32 bits

respectivamente. No lado esquerdo da tabela é mostrado o peso computacional que cada

operação tem. Este valor é depois usado para se realizar o profiling.

Instrução Descrição Peso

Word16 add (Word16 var1, Word16 var2) Short add 1Word16 sub (Word16 var1, Word16 var2) Short sub 1Word16 abs_s (Word16 var1) Short abs 1Word16 shl (Word16 var1, Word16 var2) Short shift left 1Word16 shr (Word16 var1, Word16 var2) Short shift right 1Word16 mult (Word16 var1, Word16 var2) Short mult 1Word32 L_mult (Word16 var1, Word16 var2) Long mult 1Word16 negate (Word16 var1) Short negate 1Word16 extract_h (Word32 L_var1) Extract high 1Word16 extract_l (Word32 L_var1) Extract low 1Word16 round (Word32 L_var1) Round 1Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2) Mac 1Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2) Msu 1Word32 L_macNs (Word32 L_var3, Word16 var1, Word16 var2) Mac without sat 1

Word32 L_msuNs (Word32 L_var3, Word16 var1, Word16 var2) Msu without sat 1

Word32 L_add (Word32 L_var1, Word32 L_var2) Long add 2Word32 L_sub (Word32 L_var1, Word32 L_var2) Long sub 2Word32 L_add_c (Word32 L_var1, Word32 L_var2) Long add with c 2Word32 L_sub_c (Word32 L_var1, Word32 L_var2) Long sub with c 2Word32 L_negate (Word32 L_var1) Long negate 2Word16 mult_r (Word16 var1, Word16 var2) Mult with round 2Word32 L_shl (Word32 L_var1, Word16 var2) Long shift left 2Word32 L_shr (Word32 L_var1, Word16 var2) Long shift right 2Word16 shr_r (Word16 var1, Word16 var2) Shift right with round 2Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2) Mac with rounding 2Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2) Msu with rounding 2Word32 L_deposit_h (Word16 var1) 16 bit var1 -> MSB 2Word32 L_deposit_l (Word16 var1) 16 bit var1 -> LSB 2Word32 L_shr_r (Word32 L_var1, Word16 var2) Long shift right with 3

Page 73: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 72

Pedro Mota | Pedro Santos

round Word32 L_abs (Word32 L_var1) Long abs 3Word32 L_sat (Word32 L_var1) Long saturation 4Word16 norm_s (Word16 var1) Short norm 15Word16 div_s (Word16 var1, Word16 var2) Short division 18Word16 norm_l (Word32 L_var1) Long norm 30

Tabela 14: Operações básicas usadas pela norma do codec AMR.

5.3 Uso do ficheiro count.c para realizar o profiling do codec Neste ficheiro encontra-se uma série de funções dedicadas à avaliação do peso

computacional no codec. De seguida são apresentadas as funções que interessam sobre o

ponto de vista de quem quer realizar tal avaliação ao codec.

Para isto ser feito é necessário criar-se um ‘contador’ recorrendo à função

getCounterId. Esta função retorna um inteiro que identifica o número do ‘contador’, e

recebe como parâmetro uma string que posteriormente pode ser usada pelo programa para

mostrar e identificar ao utilizador o contador em questão. Se não houver mais contadores

disponíveis a função retornará 0.

Depois de ser criado o ‘contador’ é necessário inicializá-lo. Para tal devemos, antes

de mais, seleccionar o ‘contador’. Isto é conseguido recorrendo à função setCounter, que

deve receber como parâmetro a variável que o identifica. De seguida, podemos então

chamar a função Init_WMOPS_counter. Esta função não recebe qualquer parâmetro.

Uma vez tendo o ‘contador’ pronto a operar, para o colocar em funcionamento

(contagem) basta seleccioná-lo com setCounter. A partir deste ponto do código, a

contagem associada é então feita até que um outro contador seja seleccionado ou o

programa termine.

Para se poder visualizar os resultados medidos pelos contadores devemos recorrer à

função WMOPS_output, devendo estar seleccionado o ‘contador’ pretendido.

O profiling feito por estas funções é realizado tendo em conta o tempo necessário

para se processar 1 frame de sinal (20 ms). Por esta razão sempre que se processa 1 frame

na sua totalidade deve-se chamar a função Reset_WMOPS_counter. Esta função coloca os

seus contadores a zero e atribui um peso de 0.00005 à contagem realizada até aí, ou seja,

1/20ms * 10^6. Por esta razão, é fundamental chamar-se sempre esta função quando se

processa uma frame, caso contrário os resultados finais vêm errados.

Nos resultados finais mostrados pela função WMOPS_output, vêm, por exemplo, da

seguinte forma:

Page 74: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 73

Pedro Mota | Pedro Santos

encoder:WMOPS=12.154 Average=12.125 WorstCase=12.176 WorstWC=12.274 (425 frames)

Primeiro vem identificada a parte do codec onde foi feito o profiling, no caso

‘encoder’, de seguida aparece, em WMOPS, a contagem realizada na última frame

processada (WMOPS=12.154).

É apresentada a média aritmética realizada ao longo da simulação (Average=12.125).

É ainda apresentado o pior caso verificado na simulação de uma frame

(WorstCase=12.176) e o pior dos piores casos (WorstWC=12.274).

Este último valor é avaliado tendo-se em conta uma subdivisão em várias subpartes

da porção do algoritmo a fazer o profiling e considerando-se as piores medições realizadas

nessas subpartes. Para se proceder a esta subdivisão basta recorrer-se à função fwc() nos

locais pretendidos do algoritmo.

5.4 Profiling do codec AMR

A realização do profiling do codec incidiu sobre o seu funcionamento a 12.2 kbit/s

Para se preparar o código C para a realização do profiling ao codec recorreu-se aos

ficheiros c onde é despoletado todo o processamento do codec. Estes ficheiros são coder.c

e decoder.c respectivamente para codificar e descodificar. Aqui foi adicionado ao início do

código a inicialização dos ‘contadores’ pretendidos, como explicado na secção anterior. No

final do mesmo código foi feito o printf dos resultados. No início do processamento de

cada frame de sinal é chamada a função Reset_WMOPS_counter.

Para se seleccionar os ‘contadores’ para as partes do código a realizar o profiling,

foi-se aos ficheiros sp_enc.c e cod_amr.c para o codificador e sp_dec.c e dec_amr.c

seleccionando-se aí os contadores pretendidos nas respectivas partes do algoritmo do

codec.

As variáveis inteiras que guardam as identificações dos diversos ‘contadores’ foram

declaradas no ficheiro typedef.h. Este ficheiro aparece incluído por todos os ficheiros c,

podendo-se assim usar livremente as variáveis usadas que identificam os contadores em

qualquer parte do código.

Para se compilar o programa em modo de profiling é necessário invocar o makefile

da seguinte forma:

make MODE=WMOPS

Page 75: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 74

Pedro Mota | Pedro Santos

Primeiramente realizaram-se dois testes para o codificador e descodificador: um

sem o modo dtx (discontinuous transmission) e o outro com este modo. Os resultados

obtidos foram os seguintes:

Average WorstCase WorstWorstCase sem dtx 12,125 12,176 12,274 Codificador com dtx 9,12 12,521 - sem dtx 1,854 1,942 1,957 Descodificador com dtx 1,624 1,942 -

Tabela 15: Peso computacional do codec AMR em WMOPS (weighted million operations per second).

Da última tabela é possível concluir-se que, em média, estando o codec a funcionar

em modo descontínuo (dtx), o peso computacional é muito mais baixo do que aquele

obtido no pior caso (WorstCase). Tal facto já era de esperar uma vez que codificar frames

de silêncio é mais fácil do que frames onde exista voz, fazendo então com que a média

medida baixe.

Na prática, o codec AMR funciona sempre com o modo dtx, no entanto para se

fazer uma estimativa da velocidade de relógio de um CPU é necessário considerar-se o pior

caso, sendo este aquele onde há codificação de voz. Isto é equivalente a correr o codec sem

o modo dtx, ou seja, o sinal a codificar é sempre considerado como sendo sinal de voz. Tal

facto pode ser comprovado pela tabela anterior, onde o pior caso em modo dtx é idêntico

ao caso médio sem o modo dtx.

Por estas razões, ou seja, estando todo o peso computacional na codificação de voz

propriamente dita, vamos concentrar-nos no codec sem o seu modo dtx.

Da tabela também se pode inferir acerca do desvio de padrão que eventualmente

pode sofrer o peso computacional do codec. Verifica-se aqui que os piores casos e o caso

médio lidos sem o modo dtx são idênticos. Isto significa que de uma forma geral o codec

não irá ter farmes pontuais onde, por algum motivo, o peso computacional aumente

consideravelmente.

De seguida, codificador e descodificador foram divididos em diversas partes de

forma a se medir o peso computacional de cada uma. Podem verificar-se as partes do codec

que poderão limitar o seu funcionamento em tempo real numa implementação prática.

Obteve-se as seguintes tabelas:

Page 76: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 75

Pedro Mota | Pedro Santos

Average WorstCase WorstWC

Pré-processamento 0,198 0,200 0,200 1,63% Cálculo LPC 0,612 0,614 0,614 5,05% Quantização LSP 2,134 2,163 2,163 17,60% Pitch em malha aberta 1,520 1,546 1,546 12,54% Pitch em malha fechada 2,958 2,971 2,974 24,40% Codebook inovativo 4,212 4,246 4,286 34,74% Quantização de ganhos 0,144 0,150 0,152 1,19% Act. da memória, ... 0,233 0,235 0,235 1,92% Outros .... 0,104 0,104 0,104 0,86% Total do codificador 12,125 12,176 12,274Tabela 16: Peso computacional do codificador de voz AMR no modo 12.2 kbit/s em

WMOPS.

Average WorstCase WorstWCLSF para LPC 0,127 0,129 0,129 6,85%Codebook adaptativo 0,221 0,223 0,223 11,92%Codebook inovativo 0,038 0,050 0,053 2,05%Descodificação ganhos 0,038 0,040 0,040 2,05%Construção da excitação 0,287 0,289 0,289 15,48%Filtro de síntese 0,188 0,241 0,241 10,14%Pós-filtragem 0,496 0,498 0,498 26,75%Pós-processamento 0,214 0,216 0,216 11,54%Outros .... 0,306 0,346 0,346 16,50%Toatal do descodificador 1,854 1,942 1,957Tabela 17: Peso computacional do descodificador de voz AMR no modo 12.2 kbit/s

em WMOPS.

Como já se tinha verificado anteriormente o codificador tem um peso

computacional superior ao descodificador (mais de 6 vezes).

Concentrando-nos no codificador, a pesquisa do codebook inovativo é, sem dúvida

alguma a responsável pela grande maioria do processamento do codificador e, claro está,

de todo o codec de voz AMR. Cerca de 35% do processamento realizado mas frames que

originam o maior peso computacional ao codificador, é proveniente de uma pesquisa

bastante intensiva do codebook inovativo.

Esta é a parte do codec onde deve ser feito um esforço grande para ser optimizada.

5.5 Optimização do algoritmo – pesquisa do codebook inovativo no modo 12.2 kbit/s

Na pesquisa do codebook inovativo (ou algébrico) do codificador AMR, uma

subframe de sinal (40 amostras) é dividida em algumas pistas e cada pulso, que irá

constituir o vector final do codebook, é localizado de acordo com uma estratégia nessas

Page 77: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 76

Pedro Mota | Pedro Santos

pistas por forma a se obter uma eficiente modelização do sinal de excitação para uma

subframe.

No modo 12.2 kbit/s, as 40 posições de cada subframe são divididas em 5 pistas

onde cada pista irá conter dois pulsos como mostra a tabela seguinte:

Pistas Pulsos Posições

1 i0, i5 0, 5, 10, 15, 20, 25, 30, 35 2 i1, i6 1, 6, 11, 16, 21, 26, 31, 36 3 i2, i7 2, 7, 12, 17, 22, 27, 32, 37 4 i3, i8 3, 8, 13, 18, 23, 28, 33, 38 5 i4, i9 4, 9, 14, 19, 24, 29, 34, 39

Tabela 18: Posições potenciais dos pulsos individuais no codebook algébrico para o modo 12.2 kbit/s.

Como resultado, cada vector de excitação terá 10 pulsos com amplitudes +1 ou -1

(daí o nome algébrico por vezes dado ao codebook).

O algoritmo de pesquisa do codebook começa por seleccionar o máximo global do

sinal ‘filtrado anterior’, escolhe um máximo local de uma pista na subframe e de seguida

começa a realizar pesquisas exaustivas sobre todas as possibilidades existentes em duas

pistas consecutivas (8*8=64 possibilidades) e selecciona daqui dois pulsos, um para cada

pista, que garantam o melhor sinal de excitação possível de acordo com um critério de

minimização dum erro. De seguida, passa para as outras duas pistas seguintes e faz o

mesmo. Isto é feito 4 vezes de forma a termos 8 pulsos. Os outros 2 pulsos já tinham sido

seleccionados no início do algoritmo. Isto origina um total de 8*8*4=256 possibilidades de

pulsos a pesquisar.

O algoritmo pega de seguida noutro máximo local duma pista e faz exactamente o

mesmo. Este processo repete-se no total 4 vezes para os 4 máximos locais das 4 diferentes

pistas (a pista que tem o máximo global não é considerada). Sendo assim, temos

256*4=1024 pesquisas a realizar.

O que foi feito para se diminuir o peso computacional desta parte do codec foi,

simplesmente, efectuar um maior número de conjuntos de pesquisas mas sendo estas por si

só menos extensas que as originais. Ou seja, se imaginarmos uma pesquisa em árvore,

aumentamos a profundidade da pesquisa ao longo da árvore mas cada nó terá um peso

computacional inferior.

Na pesquisa realizada pelo algoritmo da norma do codec considerou-se então

pesquisas não a duas pistas em conjunto mas sim a uma só pista isoladamente,

Page 78: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 77

Pedro Mota | Pedro Santos

0 20 40 60 80-5

-4

-3

-2

-1

0

1

2Relação sinal ruído do codec

S/N

(dB

)

Atraso da saída em relação à entrada

originalmodificado

0 20 40 60 80-6

-5

-4

-3

-2

-1

0

1

2Relação sinal ruído do codec

S/N

(dB

)

Atraso da saída em relação à entrada

originalmodificado

0 20 40 60 80-5

-4

-3

-2

-1

0

1

2

3

4

5Relação sinal ruído do codec

S/N

(dB

)

Atraso da saída em relação à entrada

originalmodificado

seleccionando apenas um pulso. Daqui resulta uma pesquisa de 8 diferentes possibilidades

em vez das anteriores 64 (8*8). Claro está que agora teremos que pesquisar 8 vezes (pistas)

até termos os 8 pulsos escolhidos. O resto do algoritmo mantém-se inalterado.

Assim sendo, passamos agora a ter um total de 8*8*4=256 pesquisas a realizar em

vez das 1024 anteriores, ou seja, uma redução de 4 vezes no número de pesquisas.

Correndo agora o programa com as alterações realizadas, verifica-se um novo peso

computacional de 10.522 WMOPS em média para este modo. Ou seja, um decréscimo de

15.2% em todo o codec em relação ao original.

Fazendo-se estas alterações é agora necessário tentar-se medir a degradação que é

produzida no novo sinal de saída.

Tratando-se este codec dum codec de voz, a avaliação da degradação do sinal de

saída deve ser feita qualitativamente e não quantitativamente, ou seja, é preciso ter-se em

linha de conta que a qualidade dum codec de voz é avaliada pelo ouvido duma pessoa.

Como não podemos avaliar o codec qualitativamente, pois não dispomos de meios

nem da experiência necessária para realizar tal avaliação, tentemos avaliá-lo

quantitativamente.

Sendo assim, mediu-se a relação sinal ruído do codec. O sinal considerou-se o sinal

de entrada e o ruído a diferença entre o sinal de entrada e o de saída.

Um dos problemas que logo à partida surge é a questão do atraso entre o sinal de

entrada e o de saída. O que se fez então, foi traçar um gráfico com a relação sinal ruído em

função de diversos atrasos. Obteve-se os seguintes gáficos:

Page 79: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 78

Pedro Mota | Pedro Santos

Nestes três gráficos analisou-se três ficheiros de áudio distintos. O primeiro é

constituído por um sinal de voz masculino e feminino; o segundo por um sinal masculino e

o terceiro por um sinal de voz feminino.

É logo notório que os gráficos do atraso da saída em relação à entrada em função da

relação sinal ruído entre a versão do algoritmo original e modificado praticamente se

sobrepõem. Isto é um bom indicador de que a modificação introduzida ao codec não

alterou a qualidade do sinal.

Outro aspecto que é importante de realçar é que nos três gráficos apresentados o

atraso que o descodificador introduz (pico máximo dos gráficos) não é exactamente o

mesmo. Isto pode ser explicado tendo em vista que o codec de voz é um sistema não linear,

ou seja, os atrasos introduzidos para diferentes frequências podem ser distintos. Note-se

que este facto não significa que o codec poderá ter um desempenho menos bom, pois,

tratando-se dum codec de voz, ou seja, sinais tipicamente com poucas frequências

distintas.

Daqui pode-se concluir que tentar quantificar a degradação introduzida ao codec

com esta alteração num valor concreto não é correcto. Se o tentássemos fazer estaríamos a

chegar a valores que apenas seriam válidos para aquele bocado de sinal de fala o que não é

representativo da qualidade em geral.

Apenas podemos, então, ouvir algumas sequências de sinais de voz que foram

descodificadas e compará-las com as obtidas originalmente. Aqui, não é perceptível

qualquer diferença entre os sinais que ouvimos pelo que podemos concluir que as

melhorias introduzidas para reduzir o peso computacional não se repercutem numa redução

na qualidade do sinal de saída do codec.

As alterações realizadas ao código podem ser consultadas no Anexo 1.

5.6 Medição das operações básicas no codec

Para se poder ter uma ideia da quantidade de vezes que uma determinada operação

básica é chamada ao longo do codec a funcionar no seu modo de 12.2 kbit/s, procedeu-se à

alteração do ficheiro count.c para se realizar tal medição.

Aqui, incluem-se mais contadores, para além dos já existentes, capazes de

contabilizar o número de chamadas a uma determinada operação básica.

Page 80: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 79

Pedro Mota | Pedro Santos

Os resultados obtidos são apresentados na tabela seguinte e incluem valores do

codificador mais descodificador a correr no modo 12.2 kbit/s sem dtx. Os valores absolutos

dos números de ocorrências são relativos a uma frame (160 amostras).

Tabela 19: Número de ocorrências médias das operações básicas do codec no modo 12.2 kbit/s por frame.

Desta tabela verifica-se que as operações de mac (multiplicar e acumular)

representam cerca de 43.5% (L_mac mais L_msu) do total das operações básicas realizadas

no codec.

As alterações realizadas sobre o ficheiro count.h encontram-se no Anexo 2.

Instrução Nº ocorrências Percentagem

L_mac 85673 35,03% DataMove16 36967 15,11% L_msu 20634 8,44% mult 18228 7,45% L_mult 14798 6,05% round 12101 4,95% add 9406 3,85% Test 9321 3,81% L_shl 8241 3,37% sub 8064 3,30% extract_h 5614 2,30% DataMove32 3137 1,28% L_shr 2463 1,01% extract_l 2161 0,88% L_sub 1998 0,82% shr 1361 0,56% Logic16 1018 0,42% L_add 840 0,34% shl 691 0,28% mult_r 480 0,20% abs_s 270 0,11%

L_deposit_h 260 0,11% L_abs 200 0,08% negate 180 0,07% norm_l 158 0,06% L_shr_r 108 0,04% norm_s 100 0,04% div_s 98 0,04% L_negate 10 0,00% L_deposit_l 6 0,00% L_macNs 0 0,00% L_msuNs 0 0,00% L_add_c 0 0,00% L_sub_c 0 0,00% shr_r 0 0,00% shift_r 0 0,00% mac_r 0 0,00% msu_r 0 0,00% L_shift_r 0 0,00% L_sat 0 0,00% Logic32 0 0,00%

Page 81: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 80

Pedro Mota | Pedro Santos

6 Pequeno programa a simular no processador – lei A

6.1 Introdução

A finalidade da implementação da lei A é testar o processador com um programa

simples.

6.2 A lei A

A Lei A é uma lei que se criou capaz de passar de forma eficiente um sinal de voz

codificado em PCM de 13 bits para outro de apenas 8 bits. Isto é conseguido tendo-se em

consideração as características típicas dum sinal de voz quanto à sua amplitude. Sabe-se

que existe uma predominância de sinais de baixa amplitude e este facto é aproveitado por

esta lei, que utiliza um maior número de bits do sinal original para a sua passagem para 8

bits quando este tem baixa amplitude. Para sinais de maiores amplitudes é feito o contrário.

Na tabela seguinte pode-se ver, de uma forma simples, como deve ser codificada a

saída de acordo com a lei A. Na tabela são apresentados valores de entrada sem o seu bit

mais significativo e o mesmo é feito no sinal codificado. A lei A define que o bit mais

significativo da entrada deve ser negado em relação ao bit mais significativo de saída.

Esta lei é definida pela recomendação G.711 da ITU-T.

Sinal entrada PCM Saída codificação

0000000wxyza 000wxyz0000001wxyza 001wxyz000001wxyzab 010wxyz00001wxyzabc 011wxyz0001wxyzabcd 100wxyz001wxyzabcde 101wxyz01wxyzabcdef 110wxyz1wxyzabcdefg 111wxyz

Tabela 20: Codificação definida pela lei A.

Page 82: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 81

Pedro Mota | Pedro Santos

6.3 Implementação da lei A no processador

No Anexo 3 pode ser vista a implementação feita em código C da lei A para ser

simulado pelo nosso processador. Como o objectivo desta parte do trabalho é executar um

programa de teste para nos ajudar na implementação do codec AMR, tentou-se que a

estrutura do código fosse o mais semelhante à do AMR. Ou seja, aqui fez-se também

processamento dos dados sobre um conjunto de amostras (160 amostras) como no codec

AMR.

Para se testar o correcto funcionamento do programa no simulador OR1k construiu-

se um ficheiro com sequências de testes de entrada e saída do codificador e descodificador

da lei A. Estas sequências de teste foram previamente obtidas do site da 3GPP.

Desta forma, construiu-se um ficheiro (um header file) onde se declararam estes

vectores em C que depois podem ser comparados com os obtidos pela simulação. O

programa começa a processar os dados frame por frame e em cada frame os dados obtidos

são verificados se estão correctos.

Em caso de erro o programa deve parar e sair com exit (-1). Se correr tudo bem, o

programa sai no fim com exit (0). Durante o processamento de cada frame é feito o report

do número da frame que foi processada.

Para criar o binário para ser usado na simulação basta correr o makefile destinado

ao mesmo. Neste makefile devem ser indicadas as dependências entre os ficheiros e

realizada a sua compilação tendo esse aspecto em consideração.

Para gerar o binário, os ficheiros objectos devem ser o a_law.o, encoder.o e o

ficheiro das excepções, except.o . As flags usadas na compilação e no linking estão bem

evidenciadas.

Após uma simulação, os resultados obtidos foram os seguintes:

report(0x00000000); report(0x00000001); report(0x00000002); report(0x00000003); report(0x00000004); report(0x00000005); report(0x00000006); report(0x00000007); report(0x00000008); report(0x00000009); report(0x0000000a); report(0x0000000b); exit(00000000) @reset : cycles 0, insn #0 @exit : cycles 6323149, insn #576437 diff : cycles 6323149, insn #576437

Page 83: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 82

Pedro Mota | Pedro Santos

Como se pode verificar a simulação correu bem. Foram processadas 12 frames de

áudio e programa saiu com exit (0). Daqui concluímos que o programa da lei A está

correctamente implementado e que tanto o simulador como o compilador fornecidos pelo

site da opencores funcionam correctamente.

Page 84: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 83

Pedro Mota | Pedro Santos

7 O caminho para a implementação do Or1k em hardware

7.1 Plataforma de desenvolvimento

A plataforma de desenvolvimento para o teste do sistema codificador/

descodificador é a carta FEUPCI, que dispõe de duas FPGAs a XCV600 e XC400, uma

memória de 128k x 32 posições da cypress, CY7C1340A, Gerador de relógio cy22150 e

módulos desenvolvidos para o DAC HI1171 (8bits, 40Msps) e o conversor ADC AD6644

de 14 bits a 65 MHz.

A FPGA XCV600 é aquela que dispõe de maior espaço disponível e por essa

mesma razão é que foi utilizada.

As limitações de espaço foram motivo para que na síntese, se tivesse que realizar a

diminuição do tamanho das caches e remoção da memória interna do processador.

No entanto como foi referido, após essas modificações, o espaço ocupado passa a

ser de 4353 slices, o que já se encontra de acordo com as especificações pretendidas em

termos de espaço.

A memória que existe na placa deve ser capaz de suportar com o programa

desenvolvido e além desta, a região de dados para o codificador/descodificador.

Os conversores AD e DA que estão disponíveis permitem, numa fase posterior de

teste, verificar se a codificação, realizando possivelmente testes em tempo real, está

correcta e se a descodificação também se executa de forma correcta.

7.2 Comunicação entre a memória e o Or1k

Em qualquer sistema envolvendo um processador, a comunicação entre dispositivos

de armazenamento é nuclear. E este caso não é excepção, pelo que o interface entre estes

deve ser apresentado de forma clara.

De acordo com as características do Or1k em termos de comunicação com o

exterior, foi visto que este dispunha do protocolo wishbone. Isso é visível no esquema do

top-level do Or1k relativamente à parte de dados quer de instruções.

Ora, o que acontece relativamente ao sistema actual é que a memória da cypress,

não apresenta qualquer interface Wishbone. Assim é obrigatório integrar esse protocolo, o

Page 85: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 84

Pedro Mota | Pedro Santos

CPU/DSP

CORE

Inst. Cache

Data Cache

Wishbone interface

Wishbone interface

Wishbone interface

Wishbone interface

Or1k top

Dispositivo que permite o acesso do

Or1k à memoria

através do protocolo Wishbone

Cypress

CY7C

1340A

DATA

Control

que pode ser feito pela construção de um módulo que implemente a comunicação com base

nessa “linguagem” entre o Or1k e a memória externa.

Figura 21: Interface necessário para realizar a comunicação com a memória da Cypress

Assim, para solucionar essa questão, consultaram-se os cores que existem na página

http://www.opencores.org/projects.cgi , e procuraram-se aqueles que suportavam o

protocolo wishbone e se relacionavam directamente com memórias.

O core que respondia às necessidades referidas era um controlador de memórias

capaz de disponibilizar a comunicação usando o protocolo Wishbone e suportando

SDRAMS, SSRAMS como é o caso da memória da Cypress e ASRAMS. Este módulo

pode ser encontrado em http://www.opencores.org/projects.cgi/web/mem_ctrl/overview,

estando disponibilizada a informação essencial sobre este, assim como o código fonte

descrito em verilog.

7.3 Controlador de Memórias

O controlador de memórias de facto surge como o elemento capaz de efectuar a

ligação entre o Or1k e a memória da Cypress integrada na plataforma de desenvolvimento.

A vantagem da utilização deste módulo é sem dúvida a flexibilidade que este tem

para se conectar a dispositivos de armazenamento, num total até 8, ocupando cada um,

regiões de memória distintas e sendo a sua configuração uma tarefa relativamente fácil de

ser executada.

Page 86: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 85

Pedro Mota | Pedro Santos

Como o controlador de memórias pode servir para realizar a ligação para diferentes

tipos de memória, este possui um controlo temporal flexível orientado para o tipo de

memória ligado a cada um dos chips select.

Por outro lado, este controlador possui a capacidade de realizar transferências do

tipo burst, desde que a memória seja capaz de responder a este tipo de operação.

Devem ser reveladas outras potencialidades deste core como é a possibilidade de

ter uma sequência de arranque padrão, geração de bits de paridade e o teste dos mesmos e

ainda a possibilidade de funcionamento em modo “power down”.

No entanto, a potencialidade mais interessante do ponto de vista da sua integração

no sistema que se pretende desenvolver, é a interface Wishbone com o processador Or1k,

sendo por esse mesmo motivo que se deseja integrar este módulo para construir a ponte de

comunicação com o exterior.

Assim poderemos ver o controlador na seguinte perspectiva: Figura 22: Modelo pretendido em relação ao controlador de memórias

A arquitectura deste controlador está descrita de forma detalhada no manual que se

encontra na página referida e onde se descarregou o código fonte. Em qualquer dos casos

julga-se necessário apresentar a figura que tenta sintetizar os blocos fundamentais inerentes

a este dispositivo.

Memory

Controller

Wishbone

Modelo de um master

que comunica

em wishbone

Ram

Data

Addr

Contro

Page 87: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 86

Pedro Mota | Pedro Santos

Figura 23:Arquitectura do controlador de memórias

Do ponto de vista do utilizador, da arquitectura apresentada, interessa a forma como

o controlador tem as suas interfaces, nomeadamente a que faz a comunicação com

periféricos que necessitam de acesso a dados de memória, e a interface destinado à

comunicação de memórias.

Além destes aspectos, deve ser realçado o facto de existirem no controlador dois

relógios. Um deles corresponde ao relógio principal que está associado ao protocolo

wishbone. O outro é obtido a partir do anterior tendo metade da sua frequência, tendo o

cuidado da sincronização deste, sendo destinado à memória presente no sistema.

7.3.1 Área ocupada pelo controlador de memórias

É claro que este controlador tem de ser integrado no sistema que se pretende

implementar, de tal forma que a sua caracterização em termos de slices ocupadas,

considerando as mesmas condições para a realização da síntese.

Page 88: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 87

Pedro Mota | Pedro Santos

De acordo com o ISE o valor encontrada para a área deste controlador é de 890

slices, pelo que adicionada à área do top level do or1k originará um sistema com 5243

slices, que está dentro dos limites da XCV600.

7.3.2 Configuração do controlador de memórias

Nesta secção pretende-se mostrar como se faz a configuração deste controlador,

através dos registos que estão associados a um determinado dispositivo. Iremos realizar a

configuração de uma memória SSRAM, que tem equivalência à da Cypress, estando este a

ocupar uma determinada localização no espaço de endereçamento. Deve ter-se em mente

que a consulta ao Anexo 16, clarifica a compreensão ao longo da explicitação.

Uma vez que os endereços usados no protocolo Wishbone são de 32 bits,

consideremos que o endereço inicial para a memória será 32’h1000_0000.

Para iniciar a configuração a primeira tarefa é definir a BA_MASK, “base address

mask, que indica qual o tamanho disponível para cada Chip Select. Esta máscara é aplicada

aos bits 21 até 28 do endereço.

A máscara a usar para o endereço pode ser 8’b1000_0000.

Para activar o chip select associado a uma determinada memória deve ser feito o

and entre o bit 28 e 21 do endereço base da memória e a máscara, e também o and entre os

bits 28 ao 21 do endereço que se pretende aceder.

A documentação relativa à configuração do registo não indica isto com clareza.

Após se terem feito as operações referidas, os resultados das mesmas devem ser

comparados, e em caso de igualdade o chip select será activado para a memória

correspondente.

Esta configuração tem de ser feita no Chip select configuration register, pelo que

seguidamente se detalha esse registo.

Os bits 23:16 contêm o endereço base de cada memória, estando a informação

descrita na documentação não totalmente correcta. A forma como se deve fazer já foi

referida e será em termos de código descrito do género:

assign cs_d = ((csc[23:16] & csc_mask[7:0]) == (addr[28:21] & csc_mask[7:0])) & csc[0];

Page 89: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 88

Pedro Mota | Pedro Santos

A operação descrita está de acordo com o que foi afirmado, pelo que o código é

sempre a fonte para retirar qualquer incongruência que se esteja a cometer na

documentação apresentada.

Os bits 15:12 são reservados, o bit 11 permite que esteja ou não habilitado o bit de

paridade, o bit 10 e 9 não têm significado para a configuração de SSRAMS, o bit 8

representa se é ou não autorizada a escrita, os bits 7:6 indicam o tamanho da memória, os

bits 5:4 indicam a largura do barramento de dados, os bits 3:1 indicam que tipo de

memória está a ser configurada, e o bit 0 permite que o chip select desta memória esteja

activo ou não.

Assim para termos a SSRAM configurada, o valor deste registo será:

Posição dos bits Access Funcionalidade Valor

31:24 ro reserved -- 23:16 rw Base address 8’h1000_0000 15:12 ro resrved --

11 rw Parity enable 1’b0 10 rw Keep row open 1’b0

Sem interesse para SSRAMs

9 rw Bank address select 1’b0 Sem interesse para

SSRAMs 8 rw Protecção de escrita 1’b0

7:6 rw Tamanho da memória 2’b00 Sem interesse para

SSRAMs 5:4 rw Tamanho do

barramento de dados 2’b10

Para SSRAMs este valor deve ser sempre

de 32bits 3:1 rw Tipo de memória 3’b001

SSRAMs 0 rw Activa ou inibe o chip

select 1’b1

Tabela 21: Configuração do Chip select register para uma memória SSRAM

Page 90: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 89

Pedro Mota | Pedro Santos

Ainda restam mais alguns registos que devem ser configurados. Estes são o tms,

time select register que define os diferentes parâmetros temporais para as memórias que se

encontram presentes no sistema.

No entanto, de acordo com a documentação, este registo não tem significado

quando se trata de SSRAMS pelo que o valor indeterminado para os seus bits serve

perfeitamente.

Ainda existe um outro registo, o control status register, que se destina a gerar os

intervalos de refrescamento orientados para as SDRAMS. Para melhor conhecimento dos

vários campos deste registo, é aconselhada a consulta do manual do controlador.

7.3.3 Aceder aos registos de configuração e ao espaço de memória

Para que se possa escrever nos registos de configuração é necessário um

descodificador de endereços. Basicamente é necessário que os endereços de entrada

tenham um determinado valor para que se possa aceder a um certo registo de configuração.

Por essa mesma razão coloca-se uma tabela retirada a partir do manual que mostra

como se pode aceder a cada um destes registos especiais orientados para executar a

configuração.

Basicamente o que acontece é que uma macro é colocada com o valor lógico 1,

quando há correspondência entre o endereço de entrada e aquele que dá acesso à escrita

nestes mesmos registos.

Page 91: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 90

Pedro Mota | Pedro Santos

Figura 24:Registos de configuração presentes no controlador de memórias

À semelhança do que acontece com o caso dos registos, também aqui deve ser feita

a descodificação associada às memórias. O procedimento é equivalente. Uma macro fica

activa quando há correspondência entre o endereço de entrada e aquele a que a memória

deve responder.

As configurações referidas são implementadas no ficheiro mc_defines.v,

onde após a sua consulta se compreende com os comentários incorporados o procedimento

para esta tarefa.

Para compreender a forma como se realiza a descodificação consideremos um

exemplo bastante simples.

Consideremos que para configurar os registos estes deviam responder aos

endereços 32’h6000_000xx. Para que a macro responsável pela selecção dos registos,

MC_REG_SEL é essencial que a comparação dos bits 31 ao 29 do endereço de entrada,

seja realizada com 001. Neste caso sempre que se pretende aceder a um registo para uma

determinada configuração, esta macro fica activa. Do ponto de vista sintáctico será:

`define MC_REG_SEL wb_addri[31:29] == 3’b001

Page 92: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 91

Pedro Mota | Pedro Santos

Assim, se quisermos aceder ao chip select 4 para a sua configuração,

32’h6000_0030, esta macro fica activa e então temos acesso ao registo pretendido.

Da mesma forma que se executa esta operação para a a selecção dos registos, para

as memórias a operação é idêntica. Imaginemos que queremos aceder aos endereços

32’h1000_0000, então a macro deve estar definida da seguinte forma, relembrando que

devemos realizar a comparação entre os bits mais significativos do endereço de entrada,

com o valor que pretendemos para a escrita/leitura da memória esteja activa. Deste modo a

compração deve ser a seguinte:

`define MC_MEM_SEL wb_addri[31:28] == 4’b0001

Neste caso qualquer endereço que satisfaça este requisito terá acesso à memória.

As macros MC_REG_SEL e MC_MEM_SEL, permitem tratar da parte da

descodificação que tem de ser obrigatoriamente implementada.

A macro MC_HAVE_CS permite indicar o número de chip selects que se pretender

ter no controlador. Atenção que a macro MC_HAVE_CS1 tem de estar sempre presente.

Existe ainda uma outra macro de interesse, que é o caso da memória que é

seleccionada para o arranque, MC_DEF_SEL. Além disso, para esta situação, existe uma

macro que contém o valor do registo temporal, MC_DEF_POR_TMS.

Para qualquer detalhe adicional, a consulta da documentação é a indicada. Com o

controlo sobre estas macros presentes no ficheiro é possível configurar o sistema de acordo

com os dispositivos que se encontram presentes.

O exemplo do testbench permite ilustrar e compreender como realizar a

configuração.

7.3.4 Testbench do controlador de memórias

Obviamente como em qualquer módulo descrito em linguagem comportamental, é

necessário que este seja validado com o recurso de um testbench. Assim neste caso o

modelo que iremos testar será o seguinte:

Page 93: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 92

Pedro Mota | Pedro Santos

Figura 25:Modelo usado no testbench

7.3.5 Descrição das unidades auxiliares para teste

O modelo do master que existe no testbench é capaz de implementar o protocolo de

comunicação wishbone e de um conjunto de rotinas que serve para a escrita, leitura e

comparação de valores em determinadas posições de memória.

De acordo com o modelo implementado para este as rotinas wbm.wb_read

(stb_delay, cyc_delay, address, data), wbm.wb_write (stb_delay, cyc_delay, address, data)

e wbm.wb_cmp (stb_delay, cyc_delay, address, data) permitem fazer a leitura, escrita, e

comparação de um determinado valor no endereço indicado, sendo possível diagnosticar

erros que estejam a acontecer, quer por time_out ou por erros de leitura ou de escrita.

Neste modelo também se encontram presentes handlers destinados à contagem de

erros quer seja até ao momento presente da análise e no final do simulação. Este modelo

está presente na secção de anexos e pode ser consultado para ver as questões de detalhe

relativamente ao protocolo Wishbone.

Ainda existem alguns módulos adicionais que servem para testar o controlador de

memórias. Podem referir-se o módulo watchdog, que verifica as questões de time-out,

como o módulo que verifica se ocorreram erros, através da análise do sinal wishbone error,

um módulo que verifica se ocorreu erro no chip select quer por estar indefinido quer pelo

acesso de vários chip selects no mesmo instante temporal. São estes os módulos que temos

de usar para testar a validade do controlador de memórias.

Memory

Controller

Wishbone

Modelo de um master

que comunica

em wishbone

Modelo da

Ram

Data

Addr

Contro

Page 94: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 93

Pedro Mota | Pedro Santos

No testbench default que foi obtido na pasta mem_ctrl/bench/richard/verilog/ está

todo o código fonte que é usado no testbench e com esses ficheiros fonte, incluindo o

mc_defines.v que se deve realizar a simulação.

Resta então mostrar que tipo de SSRAM, que vamos testar. Esta é uma memória da

Micron MT58L1MY18D, é a memória que serve de teste. Na realidade são duas memórias

deste género que são usadas no controlador. A datasheet desta SyncBurst memory pode ser

encontrada na página:

www.knt.vein.hu/cnnal/tantargyak/digitalis_rendszerek/SSRAM_MT58L1MY18D_16.pdf .

Esta memória em termos gerais é do tipo SSRAM, que na versão que se esta a usar

é 1Megx18, ou seja 1 Meg posições de memória de 18 bits e que suporta bursts tendo na

sua arquitectura dois bits que permitem o incremento do endereço interno, o que está

sempre associado a memórias deste género.

Possui como entradas síncronas, incluem todos os endereços, dados, chip enable

que funciona no nível lógico baixo, dois chips enable adicionais que permitem mais

facilidade na expansão em profundidade, e sinais de controlo de bursts (ADSC#, ADSP#,

ADV#), controlo dos bursts relacionados com cada um dos bancos de dados presentes

através de BWa# e BWb# já que existem 2 bancos, e uma entrada que permite a escrita

global GW#.

A operação de burst pode ser iniciada com ADSP e ADSC. Os endereços

subsequentes são controlados por ADV, burst advance input.

Como se pode fazer a escrita/leitura usando bytes, então aos dados do bit 0 ao 7, e

do 8 ao 15 no caso da escrita, estarão associados os sinais BWa e BWb.

As entradas assíncronas são o output enable que permite disponibilizar os dados

para o exterior, a entrada de snooze enable que coloca em suspensão a memória e a entrada

mode que permite escolher entre bursts lineares ou interleaved.

Para qualquer detalhe relativamente quer a entradas ou saídas que estejam aqui

mencionadas deve ser feita a consulta da datasheet que se encontra no site indicado.

No entanto irá apresentar-se aqui a forma como são gerados os bursts, e as formas

de onda, para o caso da leitura e da escrita.

Page 95: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 94

Pedro Mota | Pedro Santos

Figura 26: Modo de geração dos endereços quando se realizam bursts

Figura 27: Timings e formas de onda associados à leitura da memória da Micron

Page 96: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 95

Pedro Mota | Pedro Santos

Figura 28:Timings e formas de onda que estão associados à memória da Micron

Convém salientar que existe um modelo descrito em verilog e que reproduz

fielmente a memória cujas características foram apresentadas na secção anterior e que está

na pasta “mem_ctrl/bench/richard/verilog/models/”.

Se este ficheiro for analisado com atenção verificar-se-á que existem os bancos de

memória, dois como foi referido e o incremento interno do endereço quando se realizam

bursts lineares. Além disso é possível observar em que situação é que o sinal de output

enable está activo, assim como aquela em que é permitida a escrita de um determinado

banco de memória. As condições estão explícitas e respeitam a tabela de verdade que pode

ser encontrada na datasheet desta mesma memória. Todos os sinais que estão definidos no

modelo verilog respeitam a tabela de verdade referida.

Page 97: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 96

Pedro Mota | Pedro Santos

7.3.5.1 Testes pretendidos para o modelo desenvolvido e concretização

O teste que os devellopers do controlador de memória implementaram, verifica o

acesso sequencial dos endereços e numa fase posterior a acção de burst preenchendo a

memória no sentido do endereço mais elevado para o menos elevado.

A sequência de operações a realizar de acordo com o testbench correspondem à

programação do controlador de memórias:

wbm.wb_write(0, 0, 32'h6000_0008, `BA_MASK); // program base address register

wbm.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR Figura 29: Programação da mascara para o base address e do control status register

Seguido posteriormente pela chamada a uma task onde se faz a configuração do

Chip Select Configuration Register e do Timing Select Register. csc_data = { 8'h00, // reserved SSRAM_SEL, // SEL 4'h0, // reserved 1'b1, // parity enabled 1'b0, // KRO, no meaning for ssram 1'b0, // BAS, no meaning for ssram 1'b0, // WP 2'b00, // MS, no meaning for ssram 2'b10, // BW == 32bit bus. Always for ssram (maybe hardwire ???) 3'b001, // MEM_TYPE == SDRAM 1'b1 // EN == chip select enabled }; // tms_data is unused for ssrams tms_data = { 32'hx }; // program chip select registers $display("\nProgramming SSRAM chip select register.");

wbm.wb_write(0, 0, 32'h6000_0030, csc_data); // program cs4

config register (CSC4)

$display("Programming SSRAM timing register.");

wbm.wb_write(0, 0, 32'h6000_0034, tms_data); // program cs4

timing register (TMS4) Figura 30:Configuração do CSC register e TMS register

Repare-se que o CSC register está escrito na posição 30 a que corresponde ao

CSC4, o que concorda com a tabela de endereços presente na secção que foi descrita.

Seguidamente realizam-se os acessos à memória, efectuando as escritas e testando

se os valores lidos estão ou não de acordo como esperado. São também testados se os

sinais Wishbone estão de acordo com o protocolo descrito na especificação do mesmo.

Page 98: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 97

Pedro Mota | Pedro Santos

Se o ficheiro relativo ao teste sequencial de acesso à memória Anexo 7, leitura e

escrita da mesma, for consultado e se confrontar o mesmo com a execução apresentada,

estes estão de acordo.

Repare-se que não foi logo na primeira tentativa que se conseguiu realizar a

configuração do controlador, já que uma das macros necessárias à realização do mesmo

não estava activa, MC_HAVE_CS4, que estava ligada directamente à memória da Micron.

Esta foi uma das dores de cabeça…. Apesar de ter ocorrido este problema, houve a

oportunidade de ver alguns detalhes em relação ao wishbone e diagnosticar porque razão o

controlador atingia o tempo máximo do watchdog, e caso este fosse desligado em que zona

do código se encontrava.

Foi essencial verificar que sinais deveriam modificar o seu estado e porque razão

isto não era efectuado.

O resultado da execução do testbench é o seguinte:

MC_TIMING SM: Entered non existing state ... ( 0.0 ns)

# INFO: WISHBONE MASTER MODEL INSTANTIATED (bench_top.wbm)

# --- SSRAM SEQUENTIAL ACCESS TEST ---

# Programming SSRAM chip select register.

# Programming SSRAM timing register.

# SSRAM sequential test. BL = 1, CYC-delay = 0, STB-delay = 0

# Filling SSRAM memory...

# Verifying SSRAM memory contents...

# SSRAM sequential test. BL = 2, CYC-delay = 0, STB-delay = 0

# Filling SSRAM memory...

# Verifying SSRAM memory contents....

.

.

. # Current errors detected: 0

# Total errors detected: 0 Figura 31: Resultado da execução do testbench default relativo ao memory controller

7.3.5.2 Formas de onda obtidas e o protocolo wishbone

Page 99: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 98

Pedro Mota | Pedro Santos

Nada melhor que esta altura, para mostrar as formas de onda, associando-as com as

especificações dos sinais de wishbone. Iremos observar então a escrita e a leitura de um

determinado endereço, e verificar que tal acontece de acordo com as directivas indicadas

neste protocolo.

O documento que especifica este mesmo protocolo pode ser encontrado em

http://www.opencores.org/projects.cgi/web/wishbone/wbspec_b3.pdf, sendo que a

informação disponibilizada no capítulo actual deste documento foi retirada a partir do

mesmo.

Não é objectivo que neste documento se faça uma descrição exaustiva do protocolo

a nível dos seus sinais, mas ilustrar o seu funcionamento no contexto do controlador. Para

ter um conhecimento mais profundo acerca da funcionalidade de cada um dos sinais devem

ser consultadas as páginas 32 à 36 do documento que foi referido.

No entanto, apresentam-se os sinais que assumem maior relevância e os estados que

devem possuir no caso de leitura ou de escrita.

Sinal Funcionalidade

[ACK_I] The acknowledge input [ACK_I], when asserted, indicates the

normal termination of a bus cycle.

ADR_O()

The address output array [ADR_O()] is used to pass a binary

address.

CYC_O

The cycle output [CYC_O], when asserted, indicates that a valid

bus cycle is in progress.

ERR_I

The error input [ERR_I] indicates an abnormal cycle termination.

LOCK_O The lock output [LOCK_O] when asserted, indicates that the

current bus cycle is uninterruptible.

RTY_I

The retry input [RTY_I] indicates that the interface is not ready to

accept or send data, and that the cycle should be retried.

SEL_O()

The select output array [SEL_O()] indicates where valid data is

expected on the [DAT_I()] signal array during READ cycles, and

where it is placed on the [DAT_O()] signal array during WRITE

cycles.

STB_O

The strobe output [STB_O] indicates a valid data transfer cycle.

Tabela 22: Lista de sinais associados ao protocolo wishbone e respectiva funcionalidade (obtidos a partir do documento de wishbone)

Page 100: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 99

Pedro Mota | Pedro Santos

Iremos apresentar seguidamente o resultado da simulação e os respectivos sinais de

wishbone, acompanhados pela sequência de leitura/escrita.

Figura 32: Formas de onda associadas à escrita/leitura usando o protocolo wishbone

Leitura

CLOCK EDGE 0: MASTER presents a valid address on [ADR_O()] MASTER negates [WE_O] to indicate a READ cycle. MASTER presents bank select [SEL_O()] to indicate where it expects data. MASTER asserts [CYC_O] to indicate the start of the cycle. MASTER asserts [STB_O] to indicate the start of the phase. SETUP, EDGE 1: SLAVE decodes inputs, and responding SLAVE asserts [ACK_I]. SLAVE presents valid data on [DAT_I()] SLAVE asserts [ACK_I] in response to [STB_O] to indicate valid data. MASTER monitors [ACK_I], and prepares to latch data on [DAT_I()] CLOCK EDGE 1: MASTER latches data on [DAT_I()]. MASTER negates [STB_O] and [CYC_O] to indicate the end of the cycle. SLAVE negates [ACK_I] in response to negated [STB_O].

------------------------------------------Escrita----------------------------------------------

CLOCK EDGE 0: MASTER presents a valid address on [ADR_O()] MASTER presents valid data on [DAT_O()] MASTER asserts [WE_O] to indicate a WRITE cycle. MASTER presents bank select [SEL_O()] to indicate where it sends data. MASTER asserts [CYC_O] to indicate the start of the cycle. MASTER asserts [STB_O] to indicate the start of the phase.

Page 101: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 100

Pedro Mota | Pedro Santos

SETUP, EDGE 1: SLAVE decodes inputs, and responding SLAVE asserts [ACK_I]. SLAVE prepares to latch data on [DAT_O()]. SLAVE asserts [ACK_I] in response to [STB_O] to indicate latched data. MASTER monitors [ACK_I], and prepares to terminate the cycle. CLOCK EDGE 1: SLAVE latches data on [DAT_O()] MASTER negates [STB_O] and [CYC_O] to indicate the end of the cycle. SLAVE negates [ACK_I[ in response to negated [STB_O].

Figura 33:Descrição dos sinais de wishbone

Como se pode observar, as formas de onda estão de acordo com a convenção

indicada na figura anterior.

Por último basta mostrar o funcionamento da memória e o seu funcionamento em modo

burst, sendo que no modelo indicado de verilog existe a correspondência inequívoca entre

as entradas e saídas do componente físico. Quando se realiza a instanciação do mesmo no

testbench disponível no Anexo 8, para se poder simular a configuração será a seguinte (os

comentários permitem compreender o modo como é realizada esta tarefa).

mt58l1my18d ssram1 ( .Dq( {par_con[8], par_con[0], mc_dq[15:0]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[1]), .Bwb_n(mc_dqm_o[0]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) );

Figura 34: Memória instanciada no sistema

É essencial observar os Sinais de chip enable, output enable, write enable, sinais de

burst, dados e endereços relacionados com a ram.

Page 102: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 101

Pedro Mota | Pedro Santos

Figura 35: Resultado da simulação em relação aos sinais da SSRAM

Aqui é evidenciado sem dúvida o incremento interno dos endereços a ser usados

para escrita. Como estamos a usar o mode de burst linear a contagem está de acordo com o

sinal bcount o que, consultando a tabela apresentada acerca deste assunto, está correcto.

Repare-se que a descodificação está correcta.

Como neste momento foram verificados as operações descritas para a memória da

Micron, uma vez que esta é a que o testbench traz por default, é essencial que se faça o

teste agora com a memória da Cypress. As datasheets estão de acordo entre si, quer seja a

nível de IOs como funcionalidades implementadas.

A nível do testbench as modificações que devem ser implementadas reflectem-se na

desactivação das SSRAMs, e colocar esses sinais orientados para a memória da Cypress

cujo modelo está no Anexo 11, foi já descrito numa secção anterior deste documento. Esta

memória na versão implementada não aceita bit de paridade. A modificação será então a

seguinte:

CY7C1340G_PLDCD cypress (.ZZ(mc_zz_o), .Mode(1'b0), .ADDR(mc_adr_o[16:0]), .GW_N(1'b1), .BWE_N(mc_we_o), .BWd_N(mc_dqm_o[3]), .BWc_N(mc_dqm_o[2]), .BWb_N(mc_dqm_o[1]), .BWa_N(mc_dqm_o[0]), .CE1_N(mc_cs_o[4]),

Page 103: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 102

Pedro Mota | Pedro Santos

.CE2(1'b1),

.CE3_N(1'b0),

.ADSP_N(1'b1),

.ADSC_N(mc_adsc_o),

.ADV_N(mc_adv_o),

.OE_N(mc_oe_o),

.DQ (mc_dq),

.CLK (mc_clk) );

Figura 36: Modificação para fazer uso da memória da Cypress

Para correr o testbench deve ser desactivado no registo de chip select o bit de

paridade uma vez que este não é suportado por este.

Quando se realizam os testes com a memória da Cypress, os resultados são

idênticos aos da memória da Micron, o que demonstra a validade da sua implementação.

Tanto os displays que se obtém na consola, como as ondas obtidas para os sinais estão

correctos. Figura 37: Forma de ondas obtidas com a memória da Cypress

Agora que o controlador de memórias, está testado é conveniente fazer a sua

integração com o Or1k, tendo como base alguns aspectos essenciais e que serão abordados

no capítulo seguinte de forma mais detalhada.

7.4 Or1k e memory controller: necessidade de um arbitrador

O sistema que apresentamos para ser integrada com a memória da cypress

exige que haja um sistema capaz de arbitrar os acessos à memória.

Page 104: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 103

Pedro Mota | Pedro Santos

Mais uma vez fazendo uso da variedade de cores disponíveis no site dos Opencores,

www.opencores.org, encontrou-se um que com base na linguagem Perl, produzia o código

em vhdl que implementava um sistema master/slave, onde e esse aspecto tem de ser

reforçado todas as interfaces eram implementadas com o protocolo wishbone.

Este pode ser encontrado em:

http://www.opencores.org/projects.cgi/web/wb_builder/overview estando o código disponí-

vel assim como a sua respectiva documentação.

Para poder iniciar a implementação deste mesmo módulo existe um script em perl

que permite realizar essa mesma operação. O script permite definir o número de masters, o

número de slaves e o respectivo espaço de endereçamento para cada um destes últimos.

Como no caso em análise é pretendido ligar dois masters, a cache de dados e de instruções

a uma mesma memória, que será o slave, sem dúvida que esta aplicação serve os

objectivos.

Depois de se ter feito o download do ficheiro de perl este deve ser invocado da

seguinte forma :

perl wishbone.pl

Assim temos acesso a uma série de menus que permite fazer a configuração

pretendida e ter o ficheiro fonte que permite fazer a ligação entre as caches e a memória.

Pode-se alternativamente fazer as configurações, tendo como base as definições

presentes no ficheiro wishbone.defines, Anexo 10. As configurações estão coerentes com o

manual que pode ser retirado do link referido.

Iremos mostrar que configurações é que estão a ser feitas :

Page 105: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 104

Pedro Mota | Pedro Santos

Figura 38 Configuração do Wishbone builder

Para obter o vhdl sem a configuraçãp anterior deve ser invocado o seguinte comando

perl wishbone. pl –noguide wishbone.defines

Com base nas especificações pretendidas está-se apto a ter o ficheiro vhdl

produzido. Repare-se que para os masters e slaves os sinais de wishbone principais foram

os definidos na secção anterior. Os endereços para o slave responder, devem incluir a

configuração da memória e dos registos como foi salientado. No exemplo indicado para os

registos do controlador temos o endereço 32’h6000_0000 e para a memória o endereço

32’h1000_0000. Os espaços para cada um dos blocos a responder são os suficientes.

Esse ficheiro permitirá a ligação entre dois modelos de master definidos já no

testbench anterior e que têm a correspondência com as caches. É apresentado no Anexo 17

o esquema relativo à síntese deste master slave e que mostra claramente o interface

wishbone para masters e slave.

Deve ser referido que no vhdl produzido existe um erro pois há números

fraccionários que necessitam de arredondamento para inteiros e que estão no módulo de

descodificação. Este pormenor deve ser referido.

Refira-se ainda que deve ser usado um valor elevado para o somatório das

prioridades para evitar bloqueios na simulação.

Page 106: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 105

Pedro Mota | Pedro Santos

Figura 39: Modelo Master Model para teste

O ficheiro vhdl encontra-se presente na mesma directoria em que foi invocado o

script, e está em anexo neste relatório. É também colocado o testbench que reúne o modelo

de dois masters e faz a ligação entre estes e o master/slave o controlador de memória e a

SSRAM da cypress.

7.4.1 Testbench para o sistema master/slave

Para testar o modelo referido no esquema anterior, foi necessário instanciar dois

master models e o master slave fazendo a sua ligação, estando o resto do sistema

configurado como nos testbenchs anteriores. Isto está de acordo com o Anexo 13.

O primeiro teste será o seguinte:

a=0; while (1 && a < 2000) begin $display (" Escrita do master 1 \n"); wbm.wb_write(20, 10, 32'h6000_0008,

`BA_MASK); // program base address register $display (" leitura e comparação do master

1\n"); wbm.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); $display (" Escrita do master 2 \n"); wbm2.wb_write(0, 0, 32'h6000_0000,

32'h6000_0400); // program CSR // check written data $display (" leitura e comparação do master

2\n"); wbm2.wb_cmp(0, 0, 32'h6000_0000,

32'h6000_0400); a=a+1; end

Memory

Controller

WishboneModelo

do master 2

Ram

Data

Addr

Contro

Master Slave

Modelo do

master 1 Wishbone

Wishbone

Page 107: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 106

Pedro Mota | Pedro Santos

As operações correspondem a uma escrita e leitura do master 1 seguidas de uma

escrita e leitura do master 2. Os resultados na consola mostram a alternância entre estes e

os respectivos acessos.

Figura 40 : Teste do master model com acessos alternados

A análise das formas de onda revela que os acessos são alternados e que os sinais

do módulo master/slave responsável pelo arbitragem do uso do barramento de dados, estão

sempre simétricos em relação aos masters,, o que mostra que os acessos estão a ser

realizados de forma coerente.

Um outro teste que se realizou foi o master 2 estar permanentemente a tentar aceder

ao barramento para escrever nos registos csr e ba_mask e o outro a executar as operações

Page 108: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 107

Pedro Mota | Pedro Santos

de teste da memória que se realizaram nos testbenchs anteriores. Este ficheiro é o Anexo

14.

Figura 41: Resultados da execução do testbench com acesso concorrente dos masters

O último dos testes feitos, constituiu em ler um conjunto de valores carregados na

memória, que terá utilidade importantíssima no desenvolvimento posterior deste mesmo

trabalho.

8 Adaptação da norma do codec AMR à arquitectura do processador OpenRISC 1200

Nesta fase do trabalho procedeu-se à adaptação do código C que é fornecido pela

norma do codec à arquitectura do processador OpenRISC 1200. A principal alteração

realizada aqui foi a adaptação das operações básicas definidas no ficheiro basic_op.h e

basicop2.c de forma a estas serem implementadas o mais eficientemente possível.

8.1 Definição dos tipos de variáveis no OpenRISC1200

Page 109: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 108

Pedro Mota | Pedro Santos

Ao longo do código necessitamos de variáveis de 8 bits, 16 bits e 32 bits, que

devem ser definidas como Word8, Word16 e Word32 para além de uma variável de 32 bits

definida como flag.

Estas variáveis são definidas no ficheiro typedef.h que, em função da plataforma

onde é compilado o programa, define as variáveis de acordo com o seu número de bits.

É claro que este ficheiro não consegue reconhecer a plataforma de compilação do OR1k.

Sendo assim, definiu-se directamente o tipo de variáveis com o tipo de dados que é

mais habitual para 32, 16 e 8 bits e esperou-se que se tenha acertado.

O ficheiro typedef.h foi alterado como se mostra a seguir. Testes posteriores e

recorrendo-se ao código assembly verificou-se que a definição do tipo de variáveis está

correcta.

/* ******************************************************************************** * * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 * R99 Version 3.3.0 * REL-4 Version 4.1.0 * ******************************************************************************** * * File : typedef.c * Purpose : Basic types -> OR1k * ******************************************************************************** */ #ifndef typedef_h #define typedef_h "$Id $" typedef signed char Word8; typedef short Word16; typedef int Word32; typedef int Flag; #endif

8.2 Funções não reconhecidas pelo compilador do OpenRISC1200

Existe ao longo do código C chamadas a funções que não são aceites pelo

compilador do processador. Estas funções estão associadas a chamadas ao sistema

operativo ou então relacionam-se com a saída ou entrada de dados.

Estas funções são as seguintes:

• malloc; • free; • fprintf; • printf; • abort;

Page 110: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 109

Pedro Mota | Pedro Santos

• fwrite; • fread.

Começou-se por alterar as duas primeiras. Estas (malloc e free) são responsáveis

pela alocação e libertação dinâmica de memória para as estruturas definidas ao longo de

todo o código. Estas funções realizam chamadas ao sistema operativo.

Existem duas soluções possíveis para se contornar este problema. A primeira seria a

implementação dum micro sistema operativo no processador. Desta forma seria possível

alocar dinamicamente memória recorrendo a estas duas funções. Esta solução não era a

mais rápida e eficiente dado que o codec não necessita de um sistema operativo de suporte

e iria ocupar mais recursos na FPGA.

A outra solução é simplesmente abandonar-se a estrutura de alocação dinâmica de

memória e declarar-se estas variáveis normalmente como sendo globais.

A declaração dinâmica de variáveis está sempre associada às estruturas existentes

no código (designados módulos), que recorrem às funções func_init, func_reset e func_exit

já explicadas em secções anteriores. A função func_init é a responsável pela alocação da

memória. Esta função deve então ser alterada para todos os módulos.

De seguida apresenta-se um exemplo de uma função que inicializa um destes

módulos.

/* ************************************************************************** * * Function : agc_init * Purpose : Allocates memory for agc state and initializes * state memory * ************************************************************************** */ int agc_init (agcState **state) { agcState* s; if (state == (agcState **) NULL){ fprintf(stderr, "agc_init: invalid parameter\n"); return -1; } *state = NULL; /* allocate memory */ if ((s= (agcState *) malloc(sizeof(agcState))) == NULL){ fprintf(stderr, "agc_init: can not malloc state structure\n"); return -1; } agc_reset(s); *state = s; return 0; }

Page 111: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 110

Pedro Mota | Pedro Santos

Este módulo foi então modificado de forma a se ter o seguinte código. /* ************************************************************************** * * Function : agc_init * Purpose : Initializes state memory for agc state * ************************************************************************** */ int agc_init (agcState **state) { if (state == (agcState **) NULL){ fprintf(stderr, "agc_init: invalid parameter\n"); return -1; } *state = NULL; agc_reset(&agcState_s); *state = &agcState_s; return 0; }

Note-se que agora a função de inicialização só tem que fazer o reset às suas variáveis

chamando a função func_reset.

Este processo foi realizado para todos os módulos existentes no código.

A questão que se teve de ter em atenção quando se fez esta operação é que não

podemos chamar duas vezes a mesma função de inicialização, sob pena de não alocarmos

uma nova variável mas sim alterar a já existente. Este facto foi importante na inicialização

da estrutura gc_predState. Esta estrutura é declarada duas vezes pela estrutura

gainQuantSatate e uma pela estrutura Decoder_amrState. O que se fez aqui foi criar três

funções distintas de inicialização de três variáveis distintas mas todas elas do tipo

gc_predState.

Quanto à função responsável pelo reset, manteve-se inalterada.

Uma vez que deixamos de ter alocação dinâmica de memória já não precisamos de

recorrer à função de exit. Esta simplesmente foi eliminada do código.

A função de fprintf deixa de fazer sentido na implementação no OR1k, pelo que foi

eliminada. Para se evitar o desagradável trabalho de eliminar à mão todas as chamadas a

esta função definiu-se a seguinte macro:

#define fprintf{x,y} { }

Esta macro substitui todas as chamadas à função fprintf que recebam dois

parâmetros (que são as únicas existentes no código) por uma função vazia e foi colocada

no ficheiro typedef.h por ser aquele que é incluído por todos os outros.

Page 112: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 111

Pedro Mota | Pedro Santos

As funções de printf e abort também deixam de fazer sentido e apenas surgem no

ficheiro basicop2.c pelo que foram removidas manualmente.

Quanto a fread e fwrite aparecem para leitura e escrita dos ficheiros que contêm as

amostras de áudio a processar (ou processadas). Como pretendemos simular o codec no

simulador do OR1k, onde não dispomos destas funcionalidades, estas funções serão

removidas quando se preparar o código, à semelhança com o que se fez no teste da lei A,

para simular uma amostra de sinal definida num vector no código C.

Também se verificou que o compilador não reconhece a constante NULL.

Recorreu-se então a uma macro colocada no ficheiro typedef.h para definir a constante:

#define NULL 0

8.3 Optimização das operações básicas no OpenRISC1200

Como já foi dito, a norma do codec recorre a uma série de operações básicas para

realizar todas as operações aritméticas sobre as variáveis ao longo da

codificação/descodificação dum sinal. Estas operações encontram-se definidas como

funções nos ficheiros basic_op.h e basicop2.c.

8.3.1 Escrita de instruções assembly em código C Para se poder fazer uma eficiente optimização ao código C é necessário recorrer-se

à escrita de partes do código em linguagem assembly. O objectivo aqui é mesmo reescrever

todas as operações básicas definidas pela norma do codec AMR para assembly.

A escrita de uma instrução em assembly é feita recorrendo-se à directiva asm, como

se mostra a seguir: asm("l.mul\tr5,r3,r9");

Neste pequeno exemplo pode-se ver uma invocação à instrução em assembly de

multiplicação l.mul que multiplica o registo r3 por r9 e guarda o resultado em r5, isto por

definição da instrução assembly usada.

De uma forma geral não estamos interessados em usar directamente registos mas

sim variáveis declaradas no código C e associá-las então aos registos das instruções em

assembly. Isto pode ser feito como ilustra o seguinte exemplo:

Page 113: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 112

Pedro Mota | Pedro Santos

asm("l.mul\t%0,%1,%2" : "=r" (out) : "r" (var1) , "r" (var2) );

Esta instrução tem 3 parâmetros (registos no caso). Estes são invocados recorrendo-

se à sintaxe de %0, %1 e %2. Os números indicam a ordem com que as variáveis do lado

direito da expressão são invocadas. 0 significa a primeira variável, 1 a segunda variável e

assim sucessivamente. Neste exemplo a primeira variável é out, a segunda var1 e a terceira

var2. Estas variáveis, como se disse, devem ser associadas a registos. Isto é conseguido

fazendo-se, por exemplo, "r" (var1), onde r significa um registo. Outro pormenor

importante é a definição das variáveis/registos de saída. Estas devem ser chamadas da

seguinte forma: : "=r" (out) : , sempre entre o carácter de dois pontos e com "=r".

Note-se que se esta função fosse chamada da seguinte forma

asm("l.mul\t%0,%1,%2" : : "r" (out) , "r" (var1) , "r" (var2) );

não ocorreria nenhum erro na compilação do programa. No entanto, quando se fosse correr

o programa muito provavelmente ocorreriam erros, pois a variável de saída out tinha sido

associada a um registo que não era preservado na continuação da execução do programa,

sendo destruído o resultado da multiplicação.

No seguinte exemplo pode-se ver o uso a uma instrução que recorre a valores imediatos

(constantes). Isto é feito usando-se a letra i.

asm("l.addi\t%0,r0,%1" : "=r" (out) : "i" (var1) );

Aqui, var1 terá que ser uma constante e não uma variável. Se não o for, o

compilador (assemblador no caso) dá erro.

8.3.2 Colocação das operações básicas inline O primeiro teste que se fez foi a verificação se as operações básicas definidas pela

norma eram ou não colocadas inline.

É fundamental que estas funções não sejam chamadas recorrendo-se a saltos mas

sim que sejam colocadas inline ao longo de todo o código. Só assim é possível ter-se um

código que possa ser executado o mais eficientemente possível, pois o salto a uma função

implica sempre o uso de uma instrução em assembly de salto e um número que pode ser

Page 114: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 113

Pedro Mota | Pedro Santos

elevado de instruções usadas para se preservar os valores dos registos, que vão ser usados

na operação, na stack.

É crucial que todas as operações estejam inline.

Uma primeira vista ao código gerado pelo compilador, sem fazer qualquer alteração

às operações básicas, revelou que estas funções não são colocadas inline.

O que se fez foi então declarar as funções básicas como inline e observar as diferenças.

Estas foram nulas.

Quando se declara uma função como inline apenas aconselhamos o compilador a

colocá-la inline, mas não o obrigamos.

Numa tentativa de forçar o compilador a colocar estas funções inline usou-se as

seguintes directivas de compilação:

• -finline-functions; • -finline-limit=n; com n = {600, 800, 1000, etc.}; • -O3

Os resultados foram mais uma vez nulos.

Chegou-se a fazer testes a uma chamada a uma função feita por nós que apenas usa

uma instrução assembly. Mesmo assim o compilador não garantiu a sua colocação inline.

Tal situação é impensável se queremos ter um código optimizado para correr em

tempo em real.

A solução encontrada foi abandonar esta técnica, que não garante uma colocação

inline das funções, e recorrer-se ao uso de macros como é descrito na secção seguinte.

8.3.3 O uso de macros mas operações básicas

O uso de macros foi necessário para se garantir sempre que as operações básicas

existentes ao longo do código são colocadas inline. O conteúdo destas é substituído durante

o pré-processamento sempre que existe uma chamada à respectiva macro. Desta forma as

operações ficam sempre inline.

O grande problema das macros é que estas, não sendo funções, não retornam

valores.

Para se ultrapassar este problema teve-se que passar à macro mais um parâmetro

para além dos já existentes que será então o valor de retorno da operação.

Page 115: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 114

Pedro Mota | Pedro Santos

Desta forma temos que alterar manualmente todas as chamadas às operações

básicas existentes no código. Esta solução torna-se muito dispendiosa em termos de tempo,

mas foi a única encontrada que realmente funciona.

De notar que esta solução de alterar todo o código, permite níveis de optimização e

adaptação à arquitectura do processador muito grandes. Por exemplo existem diferenças

em multiplicar uma variável por outra variável ou multiplicar uma variável por uma

constante.

Se pretendermos escrever uma macro que realize uma multiplicação de forma

genérica devemos recorrer à instrução em assembly que faz a multiplicação entre dois

registos. Quando se chama esta macro para multiplicar uma variável por uma constante, o

que o compilador irá fazer, em termos de assembly, é passar a constante para um registo

auxiliar e depois usar a instrução de multiplicação, que está a ser forçada pela macro, de

multiplicação entre dois registos.

É muito mais eficiente criar duas macros distintas que realizem as multiplicações

entre dois registos e entre um registo e um valor imediato recorrendo-se às respectivas

instruções em assembly.

Estes aspectos foram explorados quando se começou a fazer as substituições no

código.

Para se definir uma macro, a título de exemplo, fez-se o seguinte:

#define mult_OR32(var_out, var1, var2){ \ Word32 aux1; \ asm volatile ( "l.mul\t%0,%1,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfeq\t%3,%0 \n"\ "l.bnf\t3 \n"\ "l.srai\t%0,%0,0x000f \n"\ "l.addi\t%0,r0,0x7fff \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (aux1) );\ }

Esta macro define a multiplicação segundo a norma do codec entre duas variáveis

de entrada de 16 bits vindo a saída em 16 bits. De notar que o primeiro parâmetro é o

resultado da operação. A invocação duma função em assembly fez-se acompanhar da

palavra volatile para se garantir que o compilador nunca mexe no código assembly escrito

por nós.

No código em C devemos chamar esta função da seguinte forma:

mult_OR32 (a, x , y);

Page 116: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 115

Pedro Mota | Pedro Santos

para substituir o seguinte código:

a = mult (x, y);

8.3.4 Alteração do código nas funções básicas De seguida apresenta-se uma breve descrição das operações básicas que foram

implementadas em assembly para adaptar à arquitectura do OPENRISC1200.

Para esta implementação, recorreu-se exaustivamente ao ficheiro basicop2.c onde

estão definidas, tanto em C como textualmente, todas as operações básicas e às operações

existentes em assembly de vírgula fixa do processador descritas no Anexo 5.

A implementação realizada destas operações encontra-se no Anexo 6.

A principal dificuldade desta parte do trabalho é o facto de quase todas estas

operações, que são definidas pela norma do codec, exigirem que o resultado seja sempre

saturado em caso de overflow. A arquitectura das operações do codec não contempla tais

instruções. A norma também define que o resultado de todas as multiplicações deve vir

multiplicado por 2.

Como se vai proceder à alteração de todas as funções do codec, aqui não foi

optimizado apenas o modo de 12.2 kbit/s mas sim todo o codec. Não vale a pena estarmos

a seleccionar as funções associadas ao modo de mais alto débito do codec e fazer-se as

alterações apenas aí.

Para se validar as alterações feitas ao código usou-se uma técnica semelhante à

descrita quando se validou o código da lei A. Usou-se as sequências de testes que podem

ser encontradas junto com os ficheiros da norma do código C: spch_dos.inp; spch_dos.cod,

spch_dos.out e allmodes.txt. Este último ficheiro altera em cada frame o modo de

funcionamento do codec, pelo que é garantido que todos os modos são executados durante

a simulação.

8.3.4.1 As flags de Overflow e Carry Estas duas variáveis são declaradas no ficheiro basic_op.h e são usadas nas

operações básicas definidas pela norma e depois transportadas para o algoritmo do codec

como variáveis globais para auxílio do seu processamento. Estas variáveis (flags) estão

relacionadas com a saturação ou transporte do carry entre funções variáveis.

Page 117: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 116

Pedro Mota | Pedro Santos

Quando se proceder à optimização das funções em assembly é preciso ter-se em

consideração o accionamento destas flags.

Fazendo uma pesquisa a todos os ficheiros do algoritmo da norma não foi

encontrada nenhuma invocação à flag de Carry com a excepção do ficheiro basicop2.c.

Aqui, as operações que a usam também não são chamadas em parte alguma do codec.

Podemos então concluir que a flag de Carry não é usada no algoritmo do codec pelo que

podemos simplesmente ignorá-la.

Quanto à flag de Overflow, é usada nos seguintes ficheiros: • agc.c • dec_amr.c • g_pitch.c

Como se tem um número tão reduzido de invocações a esta variável, vamos tentar eliminá-

las.

Quando se procedeu à análise do estilo de programação usada pela norma,

verificou-se que quando se pretendia verificar se um dado valor tinha saturado nas

operações anteriores, apenas se comparava este mesmo com o valor máximo (ou mínimo)

que este pode ter. Se fossem iguais, então é porque tinha ocorrido overflow.

Por esta razão é porque aparece tão poucas vezes o uso à flag de Overflow.

No ficheiro de g_picth.c pôde-se eliminar o uso da flag recorrendo-se a esta técnica.

Em agc.c, a flag aparentemente não faz nada, pelo que simplesmente foi retirada do

código.

No ficheiro dec_amr.c, a invocação à flag aparece antes duma chamada a uma

função. O que se fez aqui foi criar uma cópia dessa mesma função e tratar a situação de

overflow da forma descrita acima. Uma alteração a esta função ficou fora de questão pois

esta é chamada por outras partes do algoritmo que depois teriam de ser adaptadas.

Neste ponto, não são necessárias as flags de Overflow e de Carry, pelo que a tarefa

fica simplificada na optimização das operações básicas.

8.3.4.2 Instruções de adição/subtracção Para implementar estas instruções em que o resultado surge saturado em caso de

overflow, usou-se a ideia simples de que uma soma entre dois operandos de sinais

diferentes nunca origina overflow. Se os operandos tiverem o mesmo sinal e o resultado

vier com o sinal contrário, então ocorreu overflow pelo que a saída deve ser saturada. Na

subtracção fez-se algo de semelhante.

Page 118: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 117

Pedro Mota | Pedro Santos

Estas foram as instruções implementadas em assembly recorrendo-se a macros:

• add_OR32 • add_i_OR32 • L_add_OR32 • L_add_i_OR32 • sub_OR32 • L_sub_OR32

As instruções admitem operandos de 16 bits ou 32 bits (identificadas com L_).

Sempre que possível recorreu-se a operações cujo segundo parâmetro de entrada é um

valor imediato. Isto foi feito para se aproveitar as respectivas instruções em assembly

disponibilizadas pelo processador. Aqui, é preciso ter em especial atenção ao uso da

função L_add_i_OR32 que apenas permite valores imediatos de 16 bits no máximo.

Quanto às substituições realizadas ao código teve-se em especial atenção o uso que

a norma faz das operações de comparação. Aqui, todas as comparações são realizadas com

o valor zero. Para tal, a norma recorre às operações de subtracção, comparando o resultado

sempre com zero. No caso, isto não interessa, podendo simplesmente comparar duas

variáveis uma com a outra. Ou seja, todas as operações existentes no código de subtracção

dentro de if ou while foram eliminadas.

8.3.4.3 Instruções de multiplicação As multiplicações, de acordo com o que está definido pela norma, vêm sempre com

o resultado multiplicado por 2. A saída deverá ser saturada em caso de overflow.

Aqui, para se optimizar o código em assembly, teve-se em nota que a única

possibilidade de ocorrer overflow, dado que os parâmetros de entrada destas funções são

sempre em 16 bits, é quando estes são iguais ao valor mais negativo (-32768). As

operações implementadas foram as seguintes:

• mult_OR32 • mult_i_OR32 • L_mult_OR32 • L_mult_i_OR32

Mais uma vez criou-se operações que admitem como entrada valores imediatos. Os

valores de entrada são sempre em 16 bits e os de saída em 16 ou 32 conforme o caso.

Page 119: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 118

Pedro Mota | Pedro Santos

8.3.4.4 Instruções de normalização As operações implementadas foram as seguintes:

• norm_s_OR32 • norm_l_OR32

Estas duas funções retornam o número de shift lefts que o operando de entrada pode

realizar sem que ocorra overflow. Por isso aparecem sempre associadas às funções de shift

left.

8.3.4.5 Instruções shift left/right

Nestas operações a dificuldade encontrada foi a implementação da função que

realiza o shift left, pois este em caso de overflow deverá ser saturado. A técnica usada aqui

foi recorrer-se a um ciclo que realiza um shift left de apenas 1 bit em cada iteração e, antes

de se realizar a próxima iteração, verificar se o operando não irá entrar em overflow. Caso

isto aconteça o ciclo deve ser parado e a função deve retornar um valor saturado.

A implementação da instrução de shift right não apresentou qualquer dificuldade.

As operações implementadas foram as seguintes:

• shr_OR32 • shr_i_OR32 • L_shr_OR32 • L_shr_i_OR32 • shl_OR32 • shl_i_OR32 • shl_n_sat_OR32 • shl_i_n_sat_OR32 • L_shl_OR32 • L_shl_i_OR32 • L_shl_round_OR32 • L_shl_extract_h_OR32 • L_shl_n_sat_OR32 • L_shl_n_sat_OR32 • L_shl_n_sat_extract_h_OR32 • L_shl_n_sat_round_OR32

Page 120: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 119

Pedro Mota | Pedro Santos

Quanto às operações de shift right fez-se versões para parâmetros imediatos e para

variáveis nas suas duas vertentes de 16 e 32 bits.

As operações de shift left, dada a sua complexidade, tentou-se juntar com outras

operações que habitualmente aparecem juntas a ela. Tipicamente um shift left aparece

precedido de funções de normalização e procedido das funções de arredondamento ou de

extracção da parte mais significativa da variável. Quando uma normalização aparece antes

dum shift left, neste não é necessário fazer-se com saturação.

8.3.4.6 Instruções mac As instruções mac são, sem dúvida alguma, as mais críticas para realizar uma

eficiente optimização de todo o codec. Por isso é preciso ter-se especial cuidado na sua

implementação.

Como, por definição da norma, o resultado da multiplicação vem sempre

multiplicado por 2, adoptou-se aqui a estratégia de apenas fazer esta multiplicação no final

de termos todos os valores acumulados, ou seja, quando se faz a leitura do acumulador.

Desta forma, podemos usar directamente as instruções fornecidas pelo processador OR1k

sem ter que estar sempre a realizar multiplicações por 2.

Como temos um acumulador de 64 bits, assumimos que este nunca entra em

saturação.

Estas foram as instruções criadas:

• L_mac_init_0_OR32 • L_mac_OR32 • L_mac_i_OR32 • L_msu_OR32 • L_mac_out_OR32 • L_mac_out_pos_OR32 • L_mac_out_add_OR32 • L_mac_out_add_pos_OR32 • L_mac_out_round_OR32 • L_mac_out_round_pos_OR32

Estas estão divididas em três grandes grupos: as funções de inicialização do

acumulador da mac, as de mac propriamente ditas e as de leitura do acumulador da mac.

A função de inicialização é responsáveis pelo esvaziamento do acumulador da mac.

Page 121: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 120

Pedro Mota | Pedro Santos

Criou-se três operações de mac para incrementar o seu acumulador. Estas três

funções correspondem às três instruções que dispomos do processador. Uma para

multiplicar e acumular duas variáveis outra para multiplicar e acumular uma variável por

um valor imediato e outra para multiplicar e subtrair duas variáveis.

A leitura do acumulador da mac é normalmente associada à operação de

arredondamento. Estas duas operações foram então associadas.

Como temos que realizar a operação de saturação do acumulador para 32 bits criou-

se instruções que apenas saturam a valores positivos. Isto é feito pois existe inúmeras vezes

ao longo do código onde é sabido que o acumulador contém um valor positivo (cálculo de

funções de autocorrelação por exemplo) e é mais fácil saturar só a valores positivos do que

a valores positivos e negativos.

Um pormenor muito importante que é preciso ter em atenção é ao facto de por

vezes o acumulador da mac ter que ser inicializado com um dado valor. Como quando

fazemos a leitura do acumulador multiplicamos este valor por 2, vamos também

multiplicar esse valor inicializado por um factor de 2, o que originará valores incorrectos.

Uma solução é inicializar a mac com metade do valor com que era anteriormente

inicializada. Mas esta solução nem sempre é viável pois muitas das vezes não podemos

simplesmente dividir esse valor por 2. Um exemplo disto é o inicializar a mac com o valor

de 1. Se este valor for dividido por 2 o resultado (em inteiro) é 0. Para ultrapassar este

problema optou-se por inicializar o acumulador da mac quando se faz a leitura do mesmo

no final de um ciclo de incrementos. Em primeiro lugar multiplica-se o resultado final por

2 e só depois se realiza a soma que deveria ter sido feita no início. Isto resolveu o

problema.

Muitas das vezes é necessário ler-se o valor que se encontra no acumulador

continuando este posteriormente a acumular dados. Por esta razão adoptou-se a estratégia

das funções que lêem do acumulador nunca o colocarem a zero. Esta tarefa está incumbida

à instrução de inicialização.

Estas situações todas originam as funções apresentadas anteriormente.

Page 122: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 121

Pedro Mota | Pedro Santos

8.3.4.7 Outras instruções

Foram também implementadas as seguintes operações básicas:

• abs_OR32 • L_abs_OR32 • negate_OR32 • L_negate_OR32 • div_s_OR32

Estas realizam operações de cálculo do valor absoluto e de negar um valor tanto na

sua vertente de 16 bits como de 32 bits. A operação de div_s realiza uma divisão especial

onde numerador e denominador são valores positivos e o numerador deverá ser sempre

menor ou igual ao denominador. O resultado desta operação é o resto desta divisão

normalizado em 16 bits, ou seja, se numerador e denominador forem iguais o resultado

será de 32767.

8.3.5 Problemas encontrados

Quando se procedeu à substituição das funções básicas foi-se deparando com

alguns problemas.

O primeiro problema que surgiu logo à partida, foi o facto de as macros por vezes

não darem resultados correctos quando os parâmetros passados a estas eram vectores,

valores apontados ou estruturas. Este problema é aceitável e de certa forma compreendido,

pois está-se a forçar que um parâmetro de entrada da macro seja algo de complexo.

Quando se usa macros, estamos, neste caso, a forçar instruções em assembly no

meio do código C. O compilador terá que fazer a ponte entre as variáveis usadas no código

C e os registos que nós associamos às instruções em assembly.

Quando se usam variáveis como vectores ou apontadores esta tarefa por vezes não é

realizada correctamente pelo compilador.

Para se ultrapassar este problema, declararam-se variáveis auxiliares onde se

depositam as variáveis como vectores, valores apontados ou estruturas, sendo depois as

primeiras usadas nas macros.

Esta técnica resolveu o problema.

Page 123: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 122

Pedro Mota | Pedro Santos

Outro problema que surgiu foi o facto de algumas macros que necessitam de

recorrer a variáveis auxiliares não funcionarem correctamente. Para explicar vejamos o

seguinte exemplo:

#define L_add_OR32(var_out, var1, var2){\ Word32 __aux1;\ Word32 __aux2;\ asm volatile ( "l.xor\t%3,%1,%2 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.add\t%0,%1,%2 \n"\ "l.xor\t%3,%1,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t6 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ }

Repare-se como a última instrução assembly é codificada pelo compilador: L_add_OR32 (t0, L_temp1, L_temp2); f00171f0: e3 4a 60 05 l.xor r26,r10,r12 f00171f4: bd 9a 00 00 l.sfltsi r26,0x0 f00171f8: 10 00 00 0a l.bf f0017220 <_Lsp_Az+0x160> f00171fc: e0 6a 60 00 l.add r3,r10,r12 f0017200: e3 4a 18 05 l.xor r26,r10,r3 f0017204: bd 7a 00 00 l.sfgesi r26,0x0 f0017208: 10 00 00 06 l.bf f0017220 <_Lsp_Az+0x160> f001720c: bd 6a 00 00 l.sfgesi r10,0x0 f0017210: 1b 40 7f ff l.movhi r26,0x7fff f0017214: ab 5a ff ff l.ori r26,r26,0xffff f0017218: 1b 40 80 00 l.movhi r26,0x8000 f001721c: e0 7a d0 0e l.cmov r3,r26,r26

Como se pode ver as variáveis __aux1 e __aux2 foram confundidas uma com a

outra. O compilador percebeu que estas variáveis eram a mesma e como tal deviam ser

atribuídas ao mesmo registo, r26 no caso. Isto, como é óbvio, dá erro.

Este problema pode ser contornado se as duas variáveis forem inicializadas com um

valor qualquer (mas diferente um do outro).

Problemas como este nem sempre surgem, ou seja, não se sabe à partida se o uso de

variáveis que não sejam inicializadas dentro das macros podem ser confundidas uma com a

outra pelo compilador.

Algumas vezes não há problema, mas doutras dá erro. É necessário recorrer-se ao

assembly gerado pelo compilador para verificar se houve erro.

A desvantagem de se inicializar estas variáveis com um dado valor que não irá ser

utilizado é que vamos gastar instruções para tais inicializações.

Page 124: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 123

Pedro Mota | Pedro Santos

Outros problemas surgiram devido não ao compilador mas sim ao simulador.

O primeiro foi o uso da instrução de inicialização do acumulador da mac. Para tal

recorreu-se à instrução de assembly l.macrc que lê para um registo o valor do acumulador e

coloca-o a 0. Como só queremos limpar o acumulador da mac, associamos esta instrução

ao registo r0 que está sempre com o valor 0 (hardwired) como se ilustra no exemplo

seguinte:

asm volatile ( "l.macrc\tr0\n" );

Alguns testes realizados sobre esta função revelaram não haver problemas. No

entanto à medida que se continuaram a fazer os testes começaram a aparecer problemas.

Aparentemente o programa a partir de uma de uma dada altura perde-se completamente,

desalinhando mesmo a leitura das suas instruções. Se experimentarmos colocar duas vezes

consecutivas esta mesma instrução (e tem que ser duas vezes!) quando se faz a leitura do

valor de saída do acumulador na respectiva macro, o problema desaparece.

Isto é um pouco estranho!

Se em vez de usarmos o registo r0, usarmos outro qualquer registo associado à

instrução l.macrc, já nada disto acontece.

Verificou-se também que o simulador não reconhece a instrução assembly l.ff1.

O compilador aqui não apresentou problemas, reconhecendo esta instrução.

Ao longo do código foram surgindo situações onde simplesmente não se conseguiu

fazer as substituições por macros.

Estes casos aconteciam muito raramente e tentando analisar o código assembly não

era visível qualquer erro.

Numa tentativa de resolver este problema, e julgando-se que estes erros eram

devido a uma má implementação do algoritmo das macros, chamou-se em simultâneo a

macro e a função, comparando os resultados das duas. O valor retornado pela função era

simplesmente ignorado. Surpreendentemente quando se fazia isto os erros deixavam de

acontecer.

Isto acontece porque o programa é alterado localmente. O compilador codifica

então o código de maneira diferente, deixando de acontecer o erro.

Tentou-se ainda mais duas soluções para tentar perceber o problema. A primeira foi

a declaração das variáveis auxiliares na macro como volatile. Isto em nada alterou. A outra

foi a passagem como parâmetros da macro destas variáveis auxiliares. Mais uma vez não

houve efeitos.

Page 125: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 124

Pedro Mota | Pedro Santos

Este erro simplesmente não se consegue perceber.

8.4 Problemas do compilador No seguimento do que foi apresentado na secção anterior, pode-se especular sobre

o possível mau funcionamento do compilador (ou simulador). De facto, há uma série de

situações que não se compreendem muito bem porque é que acontecem e nalgumas delas o

erro ainda não se conseguiu detectar (se é que é detectável).

Existem duas situações bem distintas que ocorrem na compilação dum programa

que podem indiciar que o compilador tenha sido adaptado de outras arquitecturas de outros

processadores.

A primeira é a situação onde existe um cast de uma variável de 32 bits para uma de

16 bits. O compilador comporta-se da seguinte forma:

l.slli r18,r7,0x10 l.srai r18,r18,0x10

Aqui é feita uma cópia do registo r7 para o registo r18, sendo pelo meio feito um

cast de 32 bits para 16 bits.

A questão é que esta operação poderia ser feita recorrendo-se só a uma instrução

assembly: l.exths r18, r7

Porque é que o compilador não faz isto?

A outra situação é quando se pretende multiplicar uma variável por 5, por

exemplo. O código gerado pelo compilador aparece assim:

track = index * 5; f00165e4: bb aa 00 02 l.slli r29,r10,0x2 f00165e8: e3 7d 50 00 l.add r27,r29,r10 Repare-se que são usadas duas instruções assembly quando se poderia ter usado só uma:

l.muli r27,r10,0x5 Esta última é mais eficiente, sob o ponto de vista de tempo de execução, do que a

solução adoptada pelo compilador.

Page 126: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 125

Pedro Mota | Pedro Santos

Estas duas situações demonstram que não houve certos cuidados quando se criou o

compilador. Mais ainda, pode indicar adaptações de outros compiladores de outros

processadores que não foram totalmente bem sucedidas para o compilador do OR1k.

No paper “ Using Open Source Cores in Real Applications”, que pode ser

encontrado em http://www.escet.urjc.es/~jcastillo/paperdcis.pdf, só vem afirmar os

resultados obtidos.

De acordo com o conteúdo desse documento, o que se afirma é que as ferramentas

usadas para este processador, não são estáveis nem muito bem testadas, e quando usadas

diariamente, revelam-se bastante sujeitas a erros que não são aceitáveis quando se faz o

desenvolvimento de uma aplicação industrial.

O Compilador de C/C++ parece que está cheio de erros pois a OpenRisc port usa

pedaços de código “emprestados” de outras arquitecturas e foi desenvolvida para estar a

funcionar no mais curto espaço de tempo. Por essa mesma razão é que a solução adoptada

para resolver esta situação foi uma equipa de 4 elementos a trabalhar durante um mês

produzir código sem qualquer ligação com o que existia na versão anterior.

8.5 Melhorias observadas pelo uso das macros De seguida apresenta-se uma série de resultados que foram obtidos pelo uso de

macros em detrimento das funções usadas pela norma do codec.

Os resultados aqui apresentados foram obtidos usado a sequência de teste já

descrita anteriormente. Esta faz uma mistura de todos os modos do codec. Por isto, os

valores apresentados espelham valores médios. Nunca valores para os quais realmente

deverá ser dimensionado o valor de funcionamento do relógio do CPU, que corresponde ao

pior caso de funcionamento do codec.

Aqui pretende-se apenas ter uma ideia da percentagem que se ganha com o uso de

macros no peso computacional do codec.

A simulação do codec tal como vem definida pela norma (sem a chamada às

funções de profiling) revelou os seguintes dados antes e depois do uso das macros.

Page 127: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 126

Pedro Mota | Pedro Santos

Número de instruções obtidos da simulação

Sem macros Com macros

Codificador 1744054205 755573265

Descodificador 301430481 138492404

Tabela 23: Número de instruções obtido da simulação para o codificador e descodificador

MIPS

Sem macros Com macros

Codificador 205,2 88,9

Descodificador 35,5 16,3

Tabela 24: MIPS médio para codificador e descodificador

A primeira tabela indica o número de instruções que foram realizadas em toda a

simulação. Como sabemos o número de frames processadas (425) e a duração de cada uma

(20 ms), podemos estimar um valor médio do número de MIPS necessários à execução do

codec. Estes valores são apresentados na segunda tabela.

Como se pode concluir pelos valores apresentados pelas tabelas, existe uma

redução muito grande do valor de processamento médio necessário antes e depois do uso

de macros. No codificador tivemos uma redução de 2.30 vezes e no descodificador de 2.18

vezes.

De salientar que as funções básicas não foram todas implementadas pelo que estes

valores ainda poderão ser melhores.

Conclui-se que o uso de macros revela ser eficiente.

Page 128: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 127

Pedro Mota | Pedro Santos

9 Perspectivas de desenvolvimento futuras

Este trabalho, infelizmente, não conseguiu chegar ao seu final. Um dos principais

objectivos para se prosseguir com ele é, sem dúvida alguma, a implementação de

instruções dedicadas no processador de forma a se conseguir optimizar ao máximo o

código do codec de voz AMR.

No entanto, a continuação deste trabalho só deve ser considerada se se tiver

garantias que o compilador funciona correctamente.

9.1 Operações básicas a serem implementadas na arquitectura do OPENRISC1200

Da análise feita ao código pode-se dizer que as instruções dedicadas mais

importantes a serem implementadas no processador OR1k são as de leitura do valor do

acumulador da mac. Isto porque estas mostraram-se muito complicadas (extensas) de

serem realizadas em assembly.

Isto torna-se particularmente ineficiente quando estas funções têm de estar

constantemente a ser chamadas dentro dum ciclo for. Esta situação ocorre muitas vezes no

código, em especial a associação da operação de mac com a operação round. Esta seria

uma optimização muito importante a ser realizada.

As operações de shift left também se demonstraram muito ineficientes quando têm

que ser chamadas para garantir a saturação do seu valor de saída.

Funções com saturação de multiplicação e adição/subtracção também dariam bons

resultados.

9.2 32 bits versus 16 bits

Um dos grandes problemas da norma do codec é que esta está feita para

processadores de 16 bits e o processador que se dispõem é de 32 bits.

Uma questão que à partida pode ser logo levantada é o facto de estarmos a garantir

operações com saturação em operandos (registos do processador) de 32 bits. Seria uma

solução perfeitamente aceitável não se fazer saturação para variáveis de 16 bits. A questão

é que a maioria das operações está definida como tendo parâmetros de entrada variáveis de

Page 129: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 128

Pedro Mota | Pedro Santos

16 bits. Esta solução levaria a ter-se que pensar numa estratégia para reescrever as

operações básicas necessárias. Depois de feito isto, teríamos que declarar as variáveis do

código para 32 bits. Aqui surgiria um grande problema. É que todos os dados existentes ao

longo do código estão em 16 bits. Ou seja, a memória de dados iria duplicar e metade dos

dados que depois iriam ser lidos da memória eram ‘lixo’. Isto não pode acontecer.

Poderíamos então agrupar duas variáveis de 16 bits numa de 32 bits …

Em suma, muito provavelmente teríamos que reescreve o código todo para se evitar

o uso da saturação em variáveis de 16 bits.

Uma das principais ineficiências ao nível do código gerado para o processador, com

que nos deparamos ao longo da execução deste trabalho foi a questão dos casts que são

realizadas de termos um processador de 32 bits e muitas vezes usarmos variáveis de 16

bits. Como estamos a fazer a saturação das variáveis, os casts tornam-se redundantes.

Para se ter uma ideia da ineficiência associada a esta situação, fez-se o seguinte

teste. Foi-se ao código inicial da norma (sem o uso das macros) e declaram-se todas as

variáveis como sendo de 32 bits. Obteve-se agora uma redução de 1.2 vezes no tempo de

processamento face à situação onde existiam variáveis de 16 bits.

Desconhece-se uma forma que evite que o compilador realize casts das variáveis de

32 bits para 16 bits.

Page 130: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 129

Pedro Mota | Pedro Santos

10 Conclusões

A realização deste trabalho de acordo com os objectivos inicialmente propostos

revelou-se incompleta. Convém referir todavia, que os objectivos deste trabalho eram

demasiado ambiciosos para o tempo disponível. Foram tantas as pesquisas que se tiveram

de fazer, quer resultantes por tentativas falhadas quer por soluções a implementar, que a

filtragem da informação se torna bastante complicada.

O principal obstáculo encontrado ao longo da execução do trabalho foi a escassez

de documentação relativa ao correcto manuseamento das ferramentas que auxiliam o

processador Or1k. Estas, muitas das vezes, eram mesmo inexistentes. Tal situação resultou

num tempo gasto para se conseguir trabalhar com tais ferramentas demasiado longo.

A própria familiarização com as ferramentas usadas e o próprio ambiente onde

estão integradas foi lenta, o que se traduziu num consumo temporal elevado.

Por mais complexas que fossem as tentativas para solucionar o não funcionamento

de uma das ferramentas no Cygwin, elas foram infrutíferas e revelaram-se gastadoras de

tempo útil.

A norma do codec AMR revelou-se bem documentada e não apresentou qualquer

tipo de problemas de raiz ao nível do seu código C. Esta última encontrava-se bem

estruturada e, por isso mesmo, pronta a ser adaptada a uma dada arquitectura de um

processador.

Tentativas de optimizar o algoritmo da norma do codec para se obter

melhoramentos a nível de recursos gastos em processamento, sem degradar a qualidade do

codec, foram alcançadas com sucesso no seu modo de funcionamento de maior débito.

Aqui, obteve-se reduções de 15.2% da capacidade máxima de processamento.

O uso do compilador que é fornecido pelo processador revelou ser instável. Testes

realizados ao longo do trabalho deram a entender que, aquando da criação do compilador,

não houve cuidados em se optimizar o compilador à arquitectura do processador em toda a

sua plenitude. Crê-se mesmo que este compilador tenha sido resultado de uma reunião de

vários compiladores de outros processadores.

O uso de macros para se optimizar as operações básicas definidas pela norma do

codec revelou ser bastante eficiente. No entanto, esta fase do trabalho não foi completada

devido a erros que foram surgindo devido à compilação do programa do codec e à

excessiva extensão deste.

Page 131: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 130

Pedro Mota | Pedro Santos

É ainda de salientar que os vários cores que existem disponíveis de forma livre em

www.opencores.org, permitem que se possa construir um sistema elaborado e que surge

como a solução de pressupostos bem definidos. No entanto, existe sempre a limitação a

nível de documentação.

Page 132: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 131

Pedro Mota | Pedro Santos

11 Bibliografia

• Goldberg, R. G. A Practical Handbook of Speech Coders CRC Press 2000 • http://www.3gpp.org/ftp/Specs/html-info/26071.htm - AMR speech Codec; General

description; version 6.0.0 • http://www.3gpp.org/ftp/Specs/html-info/26073.htm - AMR speech Codec; C-

source code; version 6.0.0 • http://www.3gpp.org/ftp/Specs/html-info/26074.htm - AMR speech Codec; Test

sequences; version 6.0.0 • http://www.3gpp.org/ftp/Specs/html-info/26090.htm - AMR speech Codec;

Transcoding Functions; version 6.0.0 • http://www.3gpp.org/ftp/Specs/html-info/26093.htm - AMR speech Codec; Source

Controlled Rate operation; version 6.0.0 • http://www.3gpp.org/ftp/Specs/html-info/26094.htm - AMR Speech Codec; Voice

Activity Detector for AMR Speech Traffic Channels; version 6.0.0 • http://www.opencores.org/projects/mem_ctrl/ • http://www.opencores.org/projects/or1k/ • http://www.opencores.org/projects/wb_builder/ • ITU-T Rec. G.711: "Pulse code modulation (PCM) of voice frequencies". • ITU-T Rec. G.729: “Coding of Speech at 8 kbit/s Using Conjugate-Structure

Algrbraic Code-Excited Linear-PRediction (CS-ACELP)”. • M.Bolado, J. Castillo : “Using Open Source Cores in Real Applications”, DCIS

2003 • Opencores –Project OpenRisc 1000 • Redwan Salami, Claude Laflamme, Bruno Bessette, “ITU-T G.729 Annex A:

Reduced Complexity 8 kb/s CS-ACELP Codec for Digital Simultaneous Voice and Data”, IEEE Communications Magazine, September 1997.

Page 133: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 132

Pedro Mota | Pedro Santos

Anexo 1:Versão simplificada do algoritmo do codificador ficheiro s10_8pf.c /* ******************************************************************************** * * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 * R99 Version 3.3.0 * REL-4 Version 4.1.0 * * Versão simplificada * ------------------- * Pedro Santos * Pedro Mota Maio de 2005 * ******************************************************************************** * * File : s10_8pf.c * Purpose : Searches a 35/31 bit algebraic codebook containing * : 10/8 pulses in a frame of 40 samples. * ******************************************************************************** */ /* ******************************************************************************** * MODULE INCLUDE FILE AND VERSION ID ******************************************************************************** */ #include "s10_8pf.h" const char s10_8pf_id[] = "@(#)$Id $" s10_8pf_h; /* ******************************************************************************** * INCLUDE FILES ******************************************************************************** */ #include <stdio.h> #include <stdlib.h> #include "typedef.h" #include "basic_op.h" #include "count.h" #include "cnst.h" /* ******************************************************************************** * LOCAL VARIABLES AND TABLES ******************************************************************************** */ /************************************************************************* * * FUNCTION search_10and8i40() * * PURPOSE: Search the best codevector; determine positions of the 10/8 * pulses in the 40-sample frame. * * search_10and8i40 (10,5,5,dn, rr, ipos, pos_max, codvec); for GSMEFR * search_10and8i40 (8, 4,4,dn, rr, ipos, pos_max, codvec); for 10.2 * *************************************************************************/ #define _1_2 (Word16)(32768L/2) #define _1_4 (Word16)(32768L/4) #define _1_8 (Word16)(32768L/8) #define _1_16 (Word16)(32768L/16) #define _1_32 (Word16)(32768L/32) #define _1_64 (Word16)(32768L/64) #define _1_128 (Word16)(32768L/128) void search_10and8i40 ( Word16 nbPulse, /* i : nbpulses to find */ Word16 step, /* i : stepsize */ Word16 nbTracks, /* i : nbTracks */ Word16 dn[], /* i : correlation between target and h[] */ Word16 rr[][L_CODE], /* i : matrix of autocorrelation */ Word16 ipos[], /* i : starting position for each pulse */ Word16 pos_max[], /* i : position of maximum of dn[] */

Page 134: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 133

Pedro Mota | Pedro Santos

Word16 codvec[] /* o : algebraic codebook vector */ ) { Word16 i0, i1, i2, i3, i4, i5, i6, i7, i8=0, i9; Word16 i, j, k, pos, ia; Word16 psk, ps, ps0, ps1, sq, sq1; Word16 alpk, alp, alp_16; Word32 s, alp0, alp1; Word16 gsmefrFlag; test(); if (sub(nbPulse, 10) == 0) { gsmefrFlag=1; move16 (); } else { gsmefrFlag=0; move16 (); } /* fix i0 on maximum of correlation position */ i0 = pos_max[ipos[0]]; move16 (); /*------------------------------------------------------------------* * i1 loop: * *------------------------------------------------------------------*/ /* Default value */ psk = -1; move16 (); alpk = 1; move16 (); for (i = 0; i < nbPulse; i++) { codvec[i] = i; move16 (); } for (i = 1; i < nbTracks; i++) { i1 = pos_max[ipos[1]]; move16 (); ps0 = add (dn[i0], dn[i1]); alp0 = L_mult (rr[i0][i0], _1_16); alp0 = L_mac (alp0, rr[i1][i1], _1_16); alp0 = L_mac (alp0, rr[i0][i1], _1_8); /*----------------------------------------------------------------* * i2 loop: * *----------------------------------------------------------------*/ /* initialize 4 indices for i2 loop. */ move16 (); /* initialize "dn[i2]" pointer */ move16 (); /* initialize "rr[i2][i2]" pointer */ move16 (); /* initialize "rr[i0][i2]" pointer */ move16 (); /* initialize "rr[i1][i2]" pointer */ /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[2]; move16 (); for (i2 = ipos[2]; i2 < L_CODE; i2 += step) { /* index increment = step */ ps1 = add (ps0, dn[i2]); /* index incr= step+L_CODE */ alp1 = L_mac (alp0, rr[i2][i2], _1_16); /* index increment = step */ alp1 = L_mac (alp1, rr[i0][i2], _1_8); /* index increment = step */ alp1 = L_mac (alp1, rr[i1][i2], _1_8); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16);

Page 135: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 134

Pedro Mota | Pedro Santos

test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i2; move16 (); } } i2 = ia; move16 (); /*----------------------------------------------------------------* * i3 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); /*alp0 = L_mult (alp, _1_1);*/ alp0 = L_deposit_h (alp); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[3]; move16 (); /* initialize 5 indices for i3 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (); for (i3 = ipos[3]; i3 < L_CODE; i3 += step) { /* index increment = step */ ps1 = add (ps0, dn[i3]); alp1 = L_mac (alp0, rr[i3][i3], _1_16); /* index incr= step+L_CODE */ alp1 = L_mac (alp1, rr[i0][i3], _1_8); /* index increment = step */ alp1 = L_mac (alp1, rr[i1][i3], _1_8); /* index increment = step */ alp1 = L_mac (alp1, rr[i2][i3], _1_8); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i3; move16 (); } } i3 = ia; move16 (); /*----------------------------------------------------------------* * i4 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); alp0 = L_mult (alp, _1_2); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[4]; move16 (); /* initialize 6 indices for i4 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (); move16 (); for (i4 = ipos[4]; i4 < L_CODE; i4 += step) { /* index increment = step */ ps1 = add (ps0, dn[i4]); alp1 = L_mac (alp0, rr[i4][i4], _1_32);

Page 136: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 135

Pedro Mota | Pedro Santos

alp1 = L_mac (alp1, rr[i0][i4], _1_16); alp1 = L_mac (alp1, rr[i1][i4], _1_16); alp1 = L_mac (alp1, rr[i2][i4], _1_16); alp1 = L_mac (alp1, rr[i3][i4], _1_16); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i4; move16 (); } } i4 = ia; move16 (); /*----------------------------------------------------------------* * i5 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); /*alp0 = L_mult (alp, _1_1);*/ alp0 = L_deposit_h (alp); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[5]; move16 (); /* initialize 7 indices for i5 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (), move16 (), move16 (); for (i5 = ipos[5]; i5 < L_CODE; i5 += step) { /* index increment = step */ ps1 = add (ps0, dn[i5]); alp1 = L_mac (alp0, rr[i5][i5], _1_32); alp1 = L_mac (alp1, rr[i0][i5], _1_16); alp1 = L_mac (alp1, rr[i1][i5], _1_16); alp1 = L_mac (alp1, rr[i2][i5], _1_16); alp1 = L_mac (alp1, rr[i3][i5], _1_16); alp1 = L_mac (alp1, rr[i4][i5], _1_16); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i5; move16 (); } } i5 = ia; move16 (); /*----------------------------------------------------------------* * i6 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); alp0 = L_mult (alp, _1_2); /* Default value */

Page 137: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 136

Pedro Mota | Pedro Santos

sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[6]; move16 (); /* initialize 8 indices for i6 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (), move16 (), move16 (); move16 (); for (i6 = ipos[6]; i6 < L_CODE; i6 += step) { /* index increment = step */ ps1 = add (ps0, dn[i6]); alp1 = L_mac (alp0, rr[i6][i6], _1_64); alp1 = L_mac (alp1, rr[i0][i6], _1_32); alp1 = L_mac (alp1, rr[i1][i6], _1_32); alp1 = L_mac (alp1, rr[i2][i6], _1_32); alp1 = L_mac (alp1, rr[i3][i6], _1_32); alp1 = L_mac (alp1, rr[i4][i6], _1_32); alp1 = L_mac (alp1, rr[i5][i6], _1_32); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i6; move16 (); } } i6 = ia; move16 (); /*----------------------------------------------------------------* * i7 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); /*alp0 = L_mult (alp, _1_1);*/ alp0 = L_deposit_h (alp); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[7]; move16 (); /* initialize 9 indices for i7 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (); move16 (), move16 (), move16 (); move16 (); for (i7 = ipos[7]; i7 < L_CODE; i7 += step) { /* index increment = step */ ps1 = add (ps0, dn[i7]); alp1 = L_mac (alp0, rr[i7][i7], _1_64); alp1 = L_mac (alp1, rr[i0][i7], _1_32); alp1 = L_mac (alp1, rr[i1][i7], _1_32); alp1 = L_mac (alp1, rr[i2][i7], _1_32); alp1 = L_mac (alp1, rr[i3][i7], _1_32); alp1 = L_mac (alp1, rr[i4][i7], _1_32); alp1 = L_mac (alp1, rr[i5][i7], _1_32); alp1 = L_mac (alp1, rr[i6][i7], _1_32); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16);

Page 138: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 137

Pedro Mota | Pedro Santos

test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i7; move16 (); } } i7 = ia; move16 (); /* now finished searching a set of 8 pulses */ test(); if(gsmefrFlag != 0){ /* go on with the two last pulses for GSMEFR */ /*----------------------------------------------------------------* * i8 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); alp0 = L_mult (alp, _1_2); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 (); ia = ipos[8]; move16 (); /* initialize 10 indices for i8 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (); move16 (), move16 (), move16 (); move16 (); move16 (); for (i8 = ipos[8]; i8 < L_CODE; i8 += step) { /* index increment = step */ ps1 = add (ps0, dn[i8]); alp1 = L_mac (alp0, rr[i8][i8], _1_128); alp1 = L_mac (alp1, rr[i0][i8], _1_64); alp1 = L_mac (alp1, rr[i1][i8], _1_64); alp1 = L_mac (alp1, rr[i2][i8], _1_64); alp1 = L_mac (alp1, rr[i3][i8], _1_64); alp1 = L_mac (alp1, rr[i4][i8], _1_64); alp1 = L_mac (alp1, rr[i5][i8], _1_64); alp1 = L_mac (alp1, rr[i6][i8], _1_64); alp1 = L_mac (alp1, rr[i7][i8], _1_64); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i8; move16 (); } } i8 = ia; move16 (); /*----------------------------------------------------------------* * i9 loop: * *----------------------------------------------------------------*/ ps0 = ps; move16 (); /*alp0 = L_mult (alp, _1_1);*/ alp0 = L_deposit_h (alp); /* Default value */ sq = -1; move16 (); alp = 1; move16 (); ps = 0; move16 ();

Page 139: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 138

Pedro Mota | Pedro Santos

ia = ipos[9]; move16 (); /* initialize 11 indices for i9 loop (see i2 loop) */ move16 (); move16 (); move16 (); move16 (); move16 (); move16 (); move16 (), move16 (), move16 (); move16 (); move16 (); for (i9 = ipos[9]; i9 < L_CODE; i9 += step) { /* index increment = step */ ps1 = add (ps0, dn[i9]); alp1 = L_mac (alp0, rr[i9][i9], _1_128); alp1 = L_mac (alp1, rr[i0][i9], _1_64); alp1 = L_mac (alp1, rr[i1][i9], _1_64); alp1 = L_mac (alp1, rr[i2][i9], _1_64); alp1 = L_mac (alp1, rr[i3][i9], _1_64); alp1 = L_mac (alp1, rr[i4][i9], _1_64); alp1 = L_mac (alp1, rr[i5][i9], _1_64); alp1 = L_mac (alp1, rr[i6][i9], _1_64); alp1 = L_mac (alp1, rr[i7][i9], _1_64); alp1 = L_mac (alp1, rr[i8][i9], _1_64); sq1 = mult (ps1, ps1); alp_16 = round (alp1); s = L_msu (L_mult (alp, sq1), sq, alp_16); test (); if (s > 0) { sq = sq1; move16 (); ps = ps1; move16 (); alp = alp_16; move16 (); ia = i9; move16 (); } } }/* end gsmefrFlag */ /*---------------------------------------------------------------- * * test and memorise if this combination is better than the last one.* *----------------------------------------------------------------*/ s = L_msu (L_mult (alpk, sq), psk, alp); test (); if (s > 0) { psk = sq; move16 (); alpk = alp; move16 (); codvec[0] = i0; move16 (); codvec[1] = i1; move16 (); codvec[2] = i2; move16 (); codvec[3] = i3; move16 (); codvec[4] = i4; move16 (); codvec[5] = i5; move16 (); codvec[6] = i6; move16 (); codvec[7] = i7; move16 (); test(); if (gsmefrFlag != 0) { codvec[8] = i8; move16 (); codvec[9] = ia; move16 (); } } /*----------------------------------------------------------------* * Cyclic permutation of i1,i2,i3,i4,i5,i6,i7,(i8 and i9). * *----------------------------------------------------------------*/ pos = ipos[1]; move16 (); for (j = 1, k = 2; k < nbPulse; j++, k++) { ipos[j] = ipos[k]; move16 (); } ipos[sub(nbPulse,1)] = pos; move16 (); } /* end 1..nbTracks loop*/ }

Page 140: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 139

Pedro Mota | Pedro Santos

Anexo 2:Contagem das operações básicas da norma do codec – ficheiro count.c /*********************************************************************** * * This file contains functions for the automatic complexity calculation * $Id $ * * Versão modificada: Contagem das operações básicas * Pedro Santos * Pedro Mota * *************************************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "typedef.h" #include "count.h" /* Global counter variable for calculation of complexity weight */ BASIC_OP multiCounter[MAXCOUNTERS]; int currCounter=0; /* Zero equals global counter */ /*BASIC_OP counter;*/ const BASIC_OP op_weight = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 15, 18, 30, 1, 2, 1, 2, 2 }; const char name[][50] = { "add", /* Complexity Weight of 1 */ "sub", "abs_s", "shl", "shr", "extract_h", "extract_l", "mult", "L_mult", "negate", "round", "L_mac", "L_msu", "L_macNs", "L_msuNs", "L_add", /* Complexity Weight of 2 */ "L_sub", "L_add_c", "L_sub_c", "L_negate", "L_shl", "L_shr", "mult_r", "shr_r", "shift_r", "mac_r", "msu_r", "L_deposit_h", "L_deposit_l", "L_shr_r", /* Complexity Weight of 3 */ "L_shift_r", "L_abs", "L_sat", /* Complexity Weight of 4 */ "norm_s", /* Complexity Weight of 15 */ "div_s", /* Complexity Weight of 18 */ "norm_l", /* Complexity Weight of 30 */ "DataMove16", /* Complexity Weight of 1 */ "DataMove32", /* Complexity Weight of 2 */ "Logic16", /* Complexity Weight of 1 */ "Logic32", /* Complexity Weight of 2 */ "Test" /* Complexity Weight of 2 */

Page 141: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 140

Pedro Mota | Pedro Santos

}; /* function prototypes */ Word32 TotalWeightedOperation (void); Word32 DeltaWeightedOperation (void); /* local variable */ #if WMOPS /* Counters for separating counting for different objects */ static int maxCounter=0; static char* objectName[MAXCOUNTERS+1]; static Word16 fwc_corr[MAXCOUNTERS+1]; #define NbFuncMax 1024 static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS]; static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax]; static float total_wmops[MAXCOUNTERS]; /*--------------------------------------------------------------*/ static Word32 total_wmops_operations[MAXCOUNTERS][NbFuncMax]; /*--------------------------------------------------------------*/ static Word32 LastWOper[MAXCOUNTERS]; static char* my_strdup(const char *s) /* * duplicates UNIX function strdup() which is not ANSI standard: * -- malloc() memory area big enough to hold the string s * -- copy string into new area * -- return pointer to new area * * returns NULL if either s==NULL or malloc() fails */ { char *dup; if (s == NULL) return NULL; /* allocate memory for copy of ID string (including string terminator) */ /* NOTE: the ID strings will never be deallocated because there is no way to "destroy" a counter that is not longer needed */ if ((dup = (char *) malloc(strlen(s)+1)) == NULL) return NULL; return strcpy(dup, s); } #endif int getCounterId(char *objectNameArg) { #if WMOPS if(maxCounter>=MAXCOUNTERS-1) return 0; objectName[++maxCounter]=my_strdup(objectNameArg); return maxCounter; #else return 0; /* Dummy */ #endif } void setCounter(int counterId) { #if WMOPS if(counterId>maxCounter || counterId<0) { currCounter=0;

Page 142: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 141

Pedro Mota | Pedro Santos

return; } currCounter=counterId; #endif } #if WMOPS static Word32 WMOPS_frameStat() /* calculate the WMOPS seen so far and update the global per-frame maximum (glob_wc) */ { Word32 tot; tot = TotalWeightedOperation (); if (tot > glob_wc[currCounter]) glob_wc[currCounter] = tot; /* check if fwc() was forgotten at end of last frame */ if (tot > LastWOper[currCounter]) { if (!fwc_corr[currCounter]) { fprintf(stderr, "count: operations counted after last fwc() for '%s'; " "-> fwc() called\n", objectName[currCounter]?objectName[currCounter]:""); } fwc(); } return tot; } static void WMOPS_clearMultiCounter() { Word16 i; Word32 *ptr = (Word32 *) &multiCounter[currCounter]; for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) { *ptr++ = 0; } } #endif Word32 TotalWeightedOperation () { #if WMOPS Word16 i; Word32 tot, *ptr, *ptr2; tot = 0; ptr = (Word32 *) &multiCounter[currCounter]; ptr2 = (Word32 *) &op_weight; for (i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++) { tot += ((*ptr++) * (*ptr2++)); } return ((Word32) tot); #else return 0; /* Dummy */ #endif } Word32 DeltaWeightedOperation () { #if WMOPS Word32 NewWOper, delta; NewWOper = TotalWeightedOperation (); delta = NewWOper - LastWOper[currCounter]; LastWOper[currCounter] = NewWOper; return (delta); #else return 0; /* Dummy */ #endif }

Page 143: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 142

Pedro Mota | Pedro Santos

void move16 (void) { #if WMOPS multiCounter[currCounter].DataMove16++; #endif } void move32 (void) { #if WMOPS multiCounter[currCounter].DataMove32++; #endif } void test (void) { #if WMOPS multiCounter[currCounter].Test++; #endif } void logic16 (void) { #if WMOPS multiCounter[currCounter].Logic16++; #endif } void logic32 (void) { #if WMOPS multiCounter[currCounter].Logic32++; #endif } void Init_WMOPS_counter (void) { #if WMOPS Word16 i; /* reset function weight operation counter variable */ for (i = 0; i < NbFuncMax; i++){ wc[currCounter][i] = (Word32) 0; total_wmops_operations[currCounter][i] = (Word32)0; } glob_wc[currCounter] = 0; nbframe[currCounter] = 0; total_wmops[currCounter] = 0.0; /* initially clear all counters */ WMOPS_clearMultiCounter(); LastWOper[currCounter] = 0; funcid[currCounter] = 0; #endif } void Reset_WMOPS_counter (void) { #if WMOPS Word32 tot = WMOPS_frameStat(); Word16 i; Word32 *ptr = (Word32 *) &multiCounter[currCounter]; /* increase the frame counter --> a frame is counted WHEN IT BEGINS */ nbframe[currCounter]++; /* add wmops used in last frame to count, then reset counter */ /* (in first frame, this is a no-op */ total_wmops[currCounter] += ((float) tot) * 0.00005;

Page 144: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 143

Pedro Mota | Pedro Santos

/* clear counter before new frame starts */ /* WMOPS_clearMultiCounter();*/ LastWOper[currCounter] = 0; funcid[currCounter] = 0; /* new frame, set function id to zero */ for(i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++){ total_wmops_operations[currCounter][i] += *ptr++; } WMOPS_clearMultiCounter(); #endif } Word32 fwc (void) /* function worst case */ { #if WMOPS Word32 tot; tot = DeltaWeightedOperation (); if (tot > wc[currCounter][funcid[currCounter]]) wc[currCounter][funcid[currCounter]] = tot; funcid[currCounter]++; return (tot); #else return 0; /* Dummy */ #endif } void WMOPS_output (Word16 dtx_mode) { #if WMOPS Word16 i; Word32 tot, tot_wm, tot_wc; Word32 *ptr = (Word32 *) &multiCounter[currCounter]; FILE *fich = fopen("WMOPS.txt","a"); /* get operations since last reset (or init), but do not update the counters (except the glob_wc[] maximum) so output CAN be called in each frame without problems. The frame counter is NOT updated! */ tot = WMOPS_frameStat(); tot_wm = total_wmops[currCounter] + ((float) tot) * 0.00005; fprintf (stderr, "%10s:WMOPS=%.3f", objectName[currCounter]?objectName[currCounter]:"", ((float) tot) * 0.00005); fprintf (fich, "%10s:WMOPS=%.3f", objectName[currCounter]?objectName[currCounter]:"", ((float) tot) * 0.00005); if (nbframe[currCounter] != 0){ fprintf (stderr, " Average=%.3f", tot_wm / (float) nbframe[currCounter]); fprintf (fich, " Average=%.3f", tot_wm / (float) nbframe[currCounter]); } fprintf (stderr, " WorstCase=%.3f", ((float) glob_wc[currCounter]) * 0.00005); fprintf (fich, " WorstCase=%.3f", ((float) glob_wc[currCounter]) * 0.00005); /* Worst worst case printed only when not in DTX mode */

Page 145: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 144

Pedro Mota | Pedro Santos

if (dtx_mode == 0) { tot_wc = 0L; for (i = 0; i < funcid[currCounter]; i++) tot_wc += wc[currCounter][i]; fprintf (stderr, " WorstWC=%.3f", ((float) tot_wc) * 0.00005); fprintf (fich, " WorstWC=%.3f", ((float) tot_wc) * 0.00005); } fprintf (stderr, " (%d frames)\n", nbframe[currCounter]); fprintf (fich, " (%d frames)\n", nbframe[currCounter]); for(i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++){ total_wmops_operations[currCounter][i] += *ptr++; } if (nbframe[currCounter] != 0){ fprintf (stderr, "%10s:\n", objectName[currCounter]?objectName[currCounter]:"\n"); for(i = 0; i < (sizeof (multiCounter[currCounter])/ sizeof (Word32)); i++){ fprintf (stderr, " Instrução %s \t -> Average=%.0f\n", name[i], total_wmops_operations[currCounter][i] / (float) nbframe[currCounter]); fprintf (fich, " Instrução %s \t -> Average=%.0f\n", name[i], total_wmops_operations[currCounter][i] / (float) nbframe[currCounter]); } fprintf (stderr, " (%d frames)\n\n", nbframe[currCounter]); fprintf (fich, " (%d frames)\n\n", nbframe[currCounter]); } fclose(fich); #endif }

Page 146: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 145

Pedro Mota | Pedro Santos

Anexo 3: Implementação da lei A em código C /* ******************************************************************************** * * A-LAW (ITU-G711) * * a_law.h * * Pedro Santos - [email protected] * Pedro Mota - [email protected] * * April 2005 * ******************************************************************************** */ /* ******************************************************************************** * * Function: linear2alaw * * Purpose: A-law encoder. * * Descrition: an 16-bit integer and encodes it as A-law data. * ******************************************************************************** */ void linear2alaw( Word16 pcm_val[], /* (i) 2's complement (16-bit range) */ Word8 a_law[], /* (o) a law */ Word16 ld /* (i) number of samples */ ); /* ******************************************************************************** * * Function: alaw2linear * * Purpose: A-law decoder. * * Descrition: Convert an A-law value to 16-bit linear PCM. * ******************************************************************************** */ void alaw2linear( Word8 a_law[], /* (i) a law */ Word16 pcm_val[], /* (o) 2's complement (16-bit range) */ Word16 ld ); /* (i) number of samples */

Page 147: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 146

Pedro Mota | Pedro Santos

/* ******************************************************************************** * * A-LAW (ITU-G711) * * a_law.c * * Pedro Santos - [email protected] * Pedro Mota - [email protected] * * April 2005 * ******************************************************************************** */ typedef short Word16; typedef int Word32; typedef signed char Word8; #include "a_law.h" #define QUANT_MASK (0xf) /* Quantization field mask. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ /* ******************************************************************************** * LOCAL VARIABLES AND TABLES ******************************************************************************** */ static Word16 seg_aend[7] = {0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF/*, 0x0FFF*/}; /* ******************************************************************************** * PUBLIC PROGRAM CODE ******************************************************************************** */ /* ******************************************************************************** * * Function: linear2alaw * * Purpose: A-law encoder. * * Descrition: an 16-bit integer and encodes it as A-law data. * * Algorith: * * Linear Input Code Compressed Code * ----------------- --------------- * 0000000wxyza 000wxyz * 0000001wxyza 001wxyz * 000001wxyzab 010wxyz * 00001wxyzabc 011wxyz * 0001wxyzabcd 100wxyz * 001wxyzabcde 101wxyz * 01wxyzabcdef 110wxyz * 1wxyzabcdefg 111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. ******************************************************************************** */ void linear2alaw( Word16 pcm_val[], /* (i) 2's complement (16-bit range) */ Word8 a_law[], /* (o) a law */ Word16 ld) /* (i) number of samples */ { Word16 pcm_13; Word8 mask; Word8 seg; Word16 i;

Page 148: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 147

Pedro Mota | Pedro Santos

for(i = 0; i < ld; i++) { pcm_13 = pcm_val[i] >> 3; /* convert to 13 bits */ if (pcm_13 >= 0) { mask = 0xD5; /* sign (7th) bit = 1 */ } else { mask = 0x55; /* sign (7th) bit = 0 */ pcm_13 = -pcm_13 - 1; } /* Convert the scaled magnitude to segment number. */ for (seg = 0; seg < 7; seg++) { if (pcm_13 <= seg_aend[seg]) break; } /* Combine the sign, segment, and quantization bits. */ a_law[i] = seg << SEG_SHIFT; if (seg < 2) a_law[i] |= (Word8)(pcm_13 >> 1) & QUANT_MASK; else a_law[i] |= (Word8)(pcm_13 >> seg) & QUANT_MASK; a_law[i] = a_law[i] ^ mask; } } /* ******************************************************************************** * * Function: alaw2linear * * Purpose: A-law decoder. * * Descrition: Convert an A-law value to 16-bit linear PCM. * * Algorith: * * Linear Input Code Compressed Code * ----------------- --------------- * 0000000wxyza 000wxyz * 0000001wxyza 001wxyz * 000001wxyzab 010wxyz * 00001wxyzabc 011wxyz * 0001wxyzabcd 100wxyz * 001wxyzabcde 101wxyz * 01wxyzabcdef 110wxyz * 1wxyzabcdefg 111wxyz * ******************************************************************************** */ void alaw2linear( Word8 a_law[], /* (i) a law */ Word16 pcm_val[], /* (o) 2's complement (16-bit range) */ Word16 ld ) /* (i) number of samples */ { Word16 t; Word8 a_val; Word8 seg; Word16 i; for(i = 0; i < ld; i++) { a_val = a_law[i]; a_val ^= 0x55; t = (a_val & QUANT_MASK) << 4; /* 4 por ser 16 bits, se fossem 13 bits seria 1 */ seg = (a_val & SEG_MASK) >> SEG_SHIFT; /* select segment */ if(seg){

Page 149: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 148

Pedro Mota | Pedro Santos

t += 0x108; /* se a saida fosse de 13-bits seria 0x21 */ t <<= seg - 1; } else t += 8; /* se a saida fosse de 13-bits seria 1 */ if( a_val & SIGN_BIT ) pcm_val[i] = t; else pcm_val[i] = -t; } }

Page 150: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 149

Pedro Mota | Pedro Santos

/* ***************************************************************************** * decoder.c LEI A ***************************************************************************** */ typedef short Word16; typedef int Word32; typedef signed char Word8; #include "a_law.h" #include "speech.tab" #define L_FRAME 160 /* ***************************************************************************** * MAIN PROGRAM ***************************************************************************** */ int main (void) { Word8 *new_speech_a; /* Apontador para novo vector codificado */ Word16 speech_out[L_FRAME]; /* Vector com resultado da descodificação da frame acabada de processar */ Word32 frame; Word16 i,j; /*-----------------------------------------------------------------------* * Processa sinal frame por frame * *-----------------------------------------------------------------------*/ frame = 0; for (i=0; i<12; i++) { frame++; for(j=0; j<L_FRAME; j++) speech_out[j] = 0; new_speech_a = &sp_a[ (frame-1)*L_FRAME ]; alaw2linear(new_speech_a, speech_out, L_FRAME); for(j=0; j<L_FRAME; j++) { if( speech_out[j] != sp_out[ (frame-1)*L_FRAME + j ] ) { report (i); exit (-1); } } report (i); } exit (0); }

Page 151: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 150

Pedro Mota | Pedro Santos

/* ***************************************************************************** * encoder.c LEI A ***************************************************************************** */ typedef short Word16; typedef int Word32; typedef signed char Word8; #include "a_law.h" #include "speech.tab" #include "support.h" #define L_FRAME 160 /* ***************************************************************************** * MAIN PROGRAM ***************************************************************************** */ int main (void) { Word16 *new_speech; /* Apontador para novo vector de fala */ Word8 speech_alaw[L_FRAME];/* Vector com a codifica�o da frame actual */ Word32 frame; Word16 i,j; /*-----------------------------------------------------------------------* * Processa sinal frame por frame * *-----------------------------------------------------------------------*/ frame = 0; for (i=0; i<12; i++) { frame++; for(j=0; j<L_FRAME; j++) speech_alaw[j] = 0; new_speech = &sp[ (frame-1)*L_FRAME ]; linear2alaw(new_speech, speech_alaw, L_FRAME); for(j=0; j<L_FRAME; j++) { if( speech_alaw[j] != sp_a[ (frame-1)*L_FRAME + j ] ) { report (i); exit (-1); } } report (i); } exit (0); }

Page 152: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 151

Pedro Mota | Pedro Santos

# makefile lei A objects=except.o a_law.o encoder.o obj_clean=encoder a_law.o encoder.o CC=or32-uclinux-gcc FLAGS_2=-Wall -g -nostdlib -mhard-div FLAGS_1=-I. -I/home/pedro/or1k/or1ksim/testbench/support SUPPORTLIBS=/home/pedro/or1k/or1ksim/testbench/support/libsupport.a LD_FLAGS= -nostdlib $(SUPPORTLIBS) encoder : $(objects) $(CC) -o encoder -T.//default.ld $(objects) $(LD_FLAGS) a_law.o : a_law.c a_law.h $(CC) -c $(FLAGS_1) $(FLAGS_2) a_law.c encoder.o: encoder.c a_law.h $(CC) -c $(FLAGS_1) $(FLAGS_2) encoder.c clean : $(obj_clean) rm -f $(obj_clean)

Page 153: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 152

Pedro Mota | Pedro Santos

Anexo 4:Top level do CPU

Page 154: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 153

Pedro Mota | Pedro Santos

Anexo 5: Instruções de vírgula fixa do processador Or1k Arithmetic Instructions

Instruction: Description: 32-bit implementation: Exceptions:

l.add rD, rA, rB Add Signed rD[31:0] < - rA[31:0] + rB[31:0]

SR[CY] < - carry

SR[OV] < - overflow

Range Exception

l.addc rD,rA,rB Add Signed and Carry rD[31:0] < - rA[31:0] + rB[31:0] + SR[CY]

SR[CY] < - carry

SR[OV] < - overflow

Range Exception

l.addi rD,rA,I Add Immediate Signed rD[31:0] < - rA[31:0] + exts(Immediate)

SR[CY] < - carry

SR[OV] < - overflow

Range Exception

l.addic rD,rA,I Add Immediate Signed and Carry rD[31:0] < - rA[31:0] + exts(Immediate) + SR[CY]

SR[CY] < - carry

SR[OV] < - overflow

Range Exception

l.div rD,rA,rB Divide Signed rD[31:0] < - rA[31:0] / rB[31:0]

SR[OV] < - overflow

SR[CY] < - carry

Range Exception

l.divu rD,rA,rB Divide Unsigned rD[31:0] < - rA[31:0] / rB[31:0]

SR[OV] < - overflow

SR[CY] < - carry

Range Exception

l.mac rA,rB Multiply Signed and Accumulate temp[31:0] < - rA[31:0] * rB[31:0] None

Page 155: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 154

Pedro Mota | Pedro Santos

MACHI[31:0]MACLO[31:0] < - temp[31:0] +

MACHI[31:0]MACLO[31:0]

l.maci rB,I Multiply Immediate Signed and

Accumulate

temp[31:0] < - rA[31:0] * exts(Immediate)

MACHI[31:0]MACLO[31:0] < - temp[31:0] +

MACHI[31:0]MACLO[31:0]

None

l.msb rA,rB Multiply Signed and Subtract temp[31:0] < - rA[31:0] * rB[31:0]

MACHI[31:0]MACLO[31:0] < - MACHI[31:0]MACLO[31:0] -

temp[31:0]

None

l.mul rD,rA,rB Multiply Signed rD[31:0] < - rA[31:0] * rB[31:0]

SR[OV] < - overflow

SR[CY] < - carry

Range Exception

l.muli rD,rA,I Multiply Immediate Signed rD[31:0] < - rA[31:0] * Immediate

SR[OV] < - overflow

SR[CY] < - carry

Range Exception

l.mulu rD,rA,rB Multiply Unsigned rD[31:0] < - rA[31:0] * rB[31:0]

SR[OV] < - overflow

SR[CY] < - carry

Range Exception

l.sub rD,rA,rB Subtract Signed rD[31:0] < - rA[31:0] - rB[31:0]

SR[CY] < - carry

SR[OV] < - overflow

Range Exception

Page 156: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 155

Pedro Mota | Pedro Santos

Logical Instructions l.and rD,rA,rB And rD[31:0] < - rA[31:0] AND rB[31:0] None l.andi rD,rA,K And with Immediate Half Word rD[31:0] < - rA[31:0] AND extz(Immediate) None l.or rD,rA,rB Or rD[31:0] < - rA[31:0] OR rB[31:0] None l.ori Or with Immediate Half Word rD[31:0] < - rA[31:0] OR extz(Immediate) None l.ror rD,rA,rB Rotate Right rD[31-rB[4:0]:0] < - rA[31:rB]

rD[31:32-rB[4:0]] < - rA[rB[4:0]-1:0] None

l.rori rD,rA,L Rotate Right with Immediate rD[31-L:0] < - rA[31:L] rD[31:32-L] < - rA[L-1:0]

None

l.sll rD,rA,rB Shift Left Logical rD[31:rB[4:0]] < - rA[31-rB[4:0]:0] rD[rB[4:0]-1:0] < - 0

None

l.slli rD,rA,L Shift Left Logical with Immediate rD[31:L] < - rA[31-L:0] rD[L-1:0] < - 0

None

l.sra rD,rA,rB Shift Right Arithmetic rD[31-rB[4:0]:0] < - rA[31:rB[4:0]] rD[31:32-rB[4:0]] < - rA[31]

None

l.srai rD,rA,L Shift Right Arithmetic with Immediate rD[31-L:0] < - rA[31:L] rD[31:32-L] < - rA[31]

None

l.srl rD,rA,rB Shift Right Logical rD[31-rB[4:0]:0] < - rA[31:rB[4:0]] rD[31:32-rB[4:0]] < - 0

None

l.srli rD,rA,L Shift Right Logical with Immediate rD[31-L:0] < - rA[31:L] rD[31:32-L] < - 0

None

l.xor rD,rA,rB Exclusive Or rD[31:0] < - rA[31:0] XOR rB[31:0] None l.xori rD,rA,I Exclusive Or with Immediate Half Word rD[31:0] < - rA[31:0] XOR exts(Immediate) None

Page 157: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 156

Pedro Mota | Pedro Santos

Branch Instructions l.bf N Branch if Flag EA < - exts(Immediate < < 2) + BranchInsnAddr

PC < - EA if SR[F] set None

l.bnf N Branch if No Flag EA < - exts(Immediate < < 2) + BranchInsnAddr PC < - EA if SR[F] cleared

None

l.j N Jump PC < - exts(Immediate < < 2) + JumpInsnAddr None l.jal N Jump and Link PC < - exts(Immediate < < 2) + JumpInsnAddr

LR < - DelayInsnAddr + 4 None

l.jalr rB Jump and Link Register PC < - rB LR < - DelayInsnAddr + 4

None

l.jr rB Jump Register PC < - rB None l.rfe Return From Exception PC < - EPCR

SR < - ESR None

Page 158: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 157

Pedro Mota | Pedro Santos

Register Instructions l.cmov rD,rA,rB Conditional Move rD[31:0] < - SR[F] ? rA[31:0] : rB[31:0] None l.extbs rD,rA Extend Byte with Sign rD[31:8] < - rA[7]

rD[7:0] < - rA[7:0] None

l.extbz rD,rA Extend Byte with Zero rD[31:8] < - 0 rD[7:0] < - rA[7:0]

None

l.exths rD,rA Extend Half Word with Sign rD[31:16] < - rA[15] rD[15:0] < - rA[15:0]

None

l.exthz rD,rA Extend Half Word with Zero rD[31:16] < - 0 rD[15:0] < - rA[15:0]

None

l.extws rD,rA Extend Word with Sign rD[31:0] < - rA[31:0] None l.extwz rD,rA Extend Word with Zero rD[31:0] < - rA[31:0] None l.ff1 rD,rA,rB Find First 1 rD[31:0] < - rA[31] ? 32 : rA[30] ? 31 ... rA[0] ? 1 : 0 None l.macrc rD MAC Read and Clear synchronize-mac

rD[31:0] < - MACLO[31:0] MACLO[31:0], MACHI[31:0] <- 0

None

l.mfspr rD,rA,K Move From Special-Purpose Register rD[31:0] < - spr(rA OR Immediate) None l.movhi rD,K Move Immediate High rD[31:0] < - extz(Immediate) < < 16 None l.mtspr rA,rB,K Move To Special-Purpose Register spr(rA OR Immediate) < - rB[31:0] None l.sfeq rA,rB Set Flag if Equal SR[F] < - rA[31:0] == rB[31:0] None l.sfeqi rA,I Set Flag if Equal Immediate SR[F] < - rA[31:0] == exts(Immediate) None l.sfges rA,rB Set Flag if Greater or Equal Than Signed SR[F] < - rA[31:0] >= rB[31:0] None l.sfgesi rA,I Set Flag if Greater or Equal Than Immediate Signed SR[F] < - rA[31:0] >= exts(Immediate) None l.sfgeu rA,rB Set Flag if Greater or Equal ThanUnsigned SR[F] < - rA[31:0] >= rB[31:0] None l.sfgeui rA,I Set Flag if Greater or Equal ThanImmediate

Unsigned SR[F] < - rA[31:0] >= extz(Immediate) None

l.sfgts rA,rB Set Flag if Greater Than Signed SR[F] < - rA[31:0] > rB[31:0] None l.sfgtsi rA,I Set Flag if Greater Than Immediate

Signed SR[F] < - rA[31:0] > exts(Immediate) None

l.sfgtu rA,rB Set Flag if Greater Than Unsigned SR[F] < - rA[31:0] > rB[31:0] None l.sfgtui rA,I Set Flag if Greater Than Immediate

Unsigned SR[F] < - rA[31:0] > extz(Immediate) None

l.sfles rA,rB Set Flag if Less or Equal Than Signed SR[F] < - rA[31:0] < = rB[31:0] None

Page 159: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 158

Pedro Mota | Pedro Santos

l.sflesi rA,I Set Flag if Less or Equal Than Immediate Signed

SR[F] < - rA[31:0] < = exts(Immediate) None

l.sfleu rA,rB Set Flag if Less or Equal Than Unsigned SR[F] < - rA[31:0] < = rB[31:0] None l.sfleui rA,I Set Flag if Less or Equal Than ImmediateUnsigned SR[F] < - rA[31:0] < = extz(Immediate) None l.sflts rA,rB Set Flag if Less Than Signed SR[F] < - rA[31:0] < rB[31:0] None l.sfltsi rA,I Set Flag if Less Than Immediate Signed SR[F] < - rA[31:0] < exts(Immediate) None l.sfltu rA,rB Set Flag if Less Than Unsigned SR[F] < - rA[31:0] < rB[31:0] None l.sfltui rA,I Set Flag if Less Than Immediate Unsigned SR[F] < - rA[31:0] < extz(Immediate) None l.sfne rA,rB Set Flag if Not Equal SR[F] < - rA[31:0] != rB[31:0] None l.sfnei rA,I Set Flag if Not Equal Immediate SR[F] < - rA[31:0] != exts(Immediate) None Load/Store Instructions l.lbs rD,I(rA) Load Byte and Extend with Sign EA < - exts(Immediate) + rA[31:0]

rD[7:0] < - (EA)[7:0] rD[31:8] < - (EA)[7]

TLB miss Page fault Bus error

l.lbz rD,I(rA) Load Byte and Extend with Zero EA < - exts(Immediate) + rA[31:0] rD[7:0] < - (EA)[7:0] rD[31:8] < - 0

TLB miss Page fault Bus error

l.lhs rD,I(rA) Load Half Word and Extend with Sign

EA < - exts(Immediate) + rA[31:0] rD[15:0] < - (EA)[15:0] rD[31:16] < - (EA)[15]

TLB miss Page fault Bus error Alignment

l.lhz rD,I(rA) Load Half Word and Extend with Zero

EA < - exts(Immediate) + rA[31:0] rD[15:0] < - (EA)[15:0] rD[31:16] < - 0

TLB miss Page fault Bus error Alignment

l.lws rD,I(rA) Load Single Word and Extend wit h Sign

EA < - exts(Immediate) + rA[31:0] rD[31:0] < - (EA)[31:0]

TLB miss Page fault Bus error Alignment

l.lwz rD,I(rA) Load Single Word and Extend with Zero

EA < - exts(Immediate) + rA[31:0] rD[31:0] < - (EA)[31:0]

TLB miss Page fault Bus error

Page 160: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 159

Pedro Mota | Pedro Santos

Alignment

l.sb I(rA),rB Store Byte EA < - exts(Immediate) + rA[31:0] (EA)[7:0] < - rB[7:0]

TLB miss Page fault Bus error

l.sh I(rA),rB Store Half Word EA < - exts(Immediate) + rA[31:0] (EA)[15:0] < - rB[15:0]

TLB miss Page fault Bus error Alignment

l.sw I(rA),rB Store Single Word EA < - exts(Immediate) + rA[31:0] (EA)[31:0] < - rB[31:0]

TLB miss Page fault Bus error Alignment

Others Instructions l.csync Context Syncronization context-synchronization None l.msync Memory Syncronization memory-synchronization None l.nop K No Operation - None l.psync Pipeline Syncronization pipeline-synchronization None l.sys K System Call system-call-exception(K) System Call l.trap K Trap if SR[K] = 1 then trap-exception() Trap exception

Page 161: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 160

Pedro Mota | Pedro Santos

Anexo 6: Funções básicas da norma do codec implementadas em asssembly

#define mult_OR32(var_out, var1, var2){\ Word32 aux1;\ asm volatile ( "l.mul\t%0,%1,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfeq\t%3,%0 \n"\ "l.bnf\t3 \n"\ "l.srai\t%0,%0,0x000f \n"\ "l.addi\t%0,r0,0x7fff \n"\ : "=r" (var_out)\ : "r" (var1) , "r" (var2) , "r" (aux1) );\ } #define mult_i_OR32(var_out, var1, var2){\ Word32 aux1;\ asm volatile ( "l.muli\t%0,%1,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfeq\t%3,%0 \n"\ "l.bnf\t3 \n"\ "l.srai\t%0,%0,0x000f \n"\ "l.addi\t%0,r0,0x7fff \n"\ : "=r" (var_out)\ : "r" (var1) , "i" (var2) , "r" (aux1) );\ } #define L_mult_OR32(var_out, var1, var2){\ Word32 _aux1;\ asm volatile ( "l.mul\t%0,%1,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfeq\t%3,%0 \n"\ "l.bnf\t3 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.addi\t%0,%0,0xffff \n"\ : "=r" (var_out)\ : "r" (var1) , "r" (var2) , "r" (_aux1) );\ } #define L_mult_i_OR32(var_out, var1, var2){\ Word32 _aux1;\ asm volatile ( "l.muli\t%0,%1,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfeq\t%3,%0 \n"\ "l.bnf\t3 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.addi\t%0,%0,0xffff \n"\ : "=r" (var_out)\ : "r" (var1) , "i" (var2) , "r" (_aux1) );\ } #define L_negate_OR32(L_var_out, L_var1){\ Word32 aux1;\ asm volatile ( "l.movhi\t%2,0x8000 \n"\ "l.sfeq\t%1,%2 \n"\ "l.bnf\t4 \n"\ "l.sub\t%0,r0,%1 \n"\ "l.movhi\t%0,0x7fff \n"\ "l.ori\t%0,%0,0xffff \n"\ : "=r" (L_var_out) \ : "r" (L_var1) , "r" (aux1) );\ } #define negate_OR32(var_out, var1){\ asm volatile ( "l.sfeqi\t%1,0x8000 \n"\ "l.bnf\t3 \n"\ "l.sub\t%0,r0,%1 \n"\ "l.ori\t%0,%0,0x7fff \n"\ : "=r" (var_out) \ : "r" (var1) ); \ } #define abs_s_OR32(var_out, var1){\ asm volatile ( "l.sfgesi\t%1,0x0000 \n"\ "l.bf\t6 \n"\ "l.extws\t%0,%1 \n"\

Page 162: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 161

Pedro Mota | Pedro Santos

"l.sfeqi\t%1,0x8000 \n"\ "l.bnf\t3 \n"\ "l.sub\t%0,r0,%1 \n"\ "l.addi\t%0,r0,0x7fff\n"\ : "=r" (var_out) \ : "r" (var1) ); \ } #define L_abs_OR32(L_var_out, L_var1){\ Word32 aux1;\ asm volatile ( "l.sfgesi\t%1,0x0000 \n"\ "l.bf\t7 \n"\ "l.extws\t%0,%1 \n"\ "l.movhi\t%2,0x8000 \n"\ "l.sfeq\t%1,%2 \n"\ "l.bnf\t3 \n"\ "l.sub\t%0,r0,%1 \n"\ "l.addi\t%0,%0,0xffff\n"\ : "=r" (L_var_out) \ : "r" (L_var1) , "r" (aux1) );\ } /* --> Instruções MAC <-- */ #define L_mac_init_0_OR32(){\ Word32 __aux1;\ asm volatile ( "l.macrc\t%0 \n"\ : : "r" (__aux1) );\ } #define L_mac_OR32(var1, var2){\ asm volatile ( "l.mac\t%0,%1 \n"\ : : "r" (var1) , "r" (var2) );\ } #define L_mac_i_OR32(var1, var2){\ asm volatile ( "l.maci\t%0,%1"\ : : "r" (var1) , "i" (var2) );\ } #define L_msu_OR32(var1, var2){\ asm volatile ( "l.msb\t%0,%1"\ : : "r" (var1) , "r" (var2) );\ } #define L_mac_out_pos_OR32(L_var_out){\ Word32 __aux1=0;\ asm volatile ( "l.mfspr\t%3,r0,%1 \n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.mfspr\t%0,r0,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t6 \n"\ "l.sfltsi\t%0,0x0 \n"\ "l.bf\t4 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.j\t4 \n"\ "l.nop\t0x0 \n"\ "l.movhi\t%0,0x7fff \n"\ "l.ori\t%0,%0,0xffff \n"\ : "=r" (L_var_out) \ : "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) );\ } #define L_mac_out_add_pos_OR32(L_var1, L_var_out){\ Word32 __aux1=0;\ Word32 __aux2=8;\ asm volatile ( "l.mfspr\t%3,r0,%1 \n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t19 \n"\ "l.mfspr\t%0,r0,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t15 \n"\ "l.slli\t%0,%0,0x1 \n"\ \ "l.xor\t%3,%0,%4 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t13 \n"\ "l.add\t%0,%0,%4 \n"\

Page 163: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 162

Pedro Mota | Pedro Santos

"l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t9 \n"\ "l.sfgesi\t%4,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%5,0x8000 \n"\ \ "l.j\t4 \n"\ "l.cmov\t%0,%3,%5 \n"\ "l.movhi\t%0,0x7fff \n"\ "l.ori\t%0,%0,0xffff \n"\ : "=r" (L_var_out) \ : "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) , "r" (L_var1) , "r" (__aux2));\ } #define L_mac_out_OR32(L_var_out){\ Word32 __aux1=0;\ asm volatile ( "l.mfspr\t%3,r0,%1 \n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t13 \n"\ "l.sfltsi\t%3,0xffff \n"\ "l.bf\t14 \n"\ "l.mfspr\t%0,r0,%2 \n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t7 \n"\ "l.movhi\t%3,0xc000 \n"\ "l.sfles\t%0,%3 \n"\ "l.bf\t7 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.j\t6 \n"\ "l.nop\t0x0 \n"\ "l.movhi\t%0,0x7fff \n"\ "l.j\t3 \n"\ "l.ori\t%0,%0,0xffff \n"\ "l.movhi\t%0,0x8000 \n"\ : "=r" (L_var_out) \ : "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) );\ } #define L_mac_out_add_OR32(L_var1, L_var_out){\ Word32 __aux1=0;\ Word32 __aux2=8;\ asm volatile ( "l.mfspr\t%3,r0,%1\n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t13 \n"\ "l.sfltsi\t%3,0xffff\n"\ "l.bf\t14 \n"\ "l.mfspr\t%0,r0,%2\n"\ "l.movhi\t%3,0x4000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t18 \n"\ "l.movhi\t%3,0xc000 \n"\ "l.sfles\t%0,%3 \n"\ "l.bf\t18 \n"\ "l.slli\t%0,%0,0x1\n"\ \ "l.xor\t%3,%0,%4 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t15 \n"\ "l.add\t%0,%0,%4 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t11 \n"\ "l.sfgesi\t%4,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff\n"\ "l.movhi\t%5,0x8000 \n"\ \ "l.j\t6 \n"\ "l.cmov\t%0,%3,%5 \n"\ "l.movhi\t%0,0x7fff \n"\ "l.j\t3 \n"\ "l.ori\t%0,%0,0xffff\n"\ "l.movhi\t%0,0x8000 \n"\ : "=r" (L_var_out) \

Page 164: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 163

Pedro Mota | Pedro Santos

: "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) , "r" (L_var1) , "r" (__aux2));\ } #define L_mac_out_round_OR32(var_out){\ Word32 __aux1=0;\ asm volatile ( "l.mfspr\t%3,r0,%1 \n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t16 \n"\ "l.sfltsi\t%3,0xffff \n"\ "l.bf\t17 \n"\ "l.mfspr\t%0,r0,%2 \n"\ "l.movhi\t%3,0x3fff \n"\ "l.ori\t%3,%3,0xc000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t9 \n"\ "l.movhi\t%3,0xc000 \n"\ "l.sfles\t%0,%3 \n"\ "l.bf\t9 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.ori\t%3,r0,0x8000 \n"\ "l.add\t%0,%0,%3 \n"\ "l.j\t6 \n"\ "l.srai\t%0,%0,0x10 \n"\ "l.addi\t%0,r0,0x7fff \n"\ "l.j\t3 \n"\ "l.nop 0x0 \n"\ "l.addi\t%0,r0,0x8000 \n"\ : "=r" (var_out) \ : "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) );\ } #define L_mac_out_round_pos_OR32(var_out){\ Word32 __aux1=0;\ asm volatile ( "l.mfspr\t%3,r0,%1 \n"\ "l.sfgtsi\t%3,0x0 \n"\ "l.bf\t16 \n"\ "l.sfltsi\t%3,0xffff \n"\ "l.bf\t17 \n"\ "l.mfspr\t%0,r0,%2 \n"\ "l.movhi\t%3,0x3fff \n"\ "l.ori\t%3,%3,0xc000 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t9 \n"\ "l.movhi\t%3,0xc000 \n"\ "l.sfles\t%0,%3 \n"\ "l.bf\t9 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.ori\t%3,r0,0x8000 \n"\ "l.add\t%0,%0,%3 \n"\ "l.j\t6 \n"\ "l.srai\t%0,%0,0x10 \n"\ "l.addi\t%0,r0,0x7fff \n"\ "l.j\t3 \n"\ "l.nop 0x0 \n"\ "l.addi\t%0,r0,0x8000 \n"\ : "=r" (var_out) \ : "K" (SPR_MACHI) , "K" (SPR_MACLO) , "r" (__aux1) );\ } /* --> fim instruções MAC <-- */ #define add_OR32(var_out, var1, var2){\ volatile Word32 __aux1=0;\ volatile Word32 __aux2=var1;\ asm volatile ( \ \ "l.xor\t%3,%1,%2 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.add\t%0,%1,%2 \n"\ "l.exths\t%0,%0 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t5 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.addi\t%3,r0,0x7fff \n"\ "l.addi\t%4,r0,0x8000 \n"\

Page 165: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 164

Pedro Mota | Pedro Santos

"l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define sub_OR32(var_out, var1, var2){\ volatile Word32 __aux1;\ volatile Word32 __aux2=var1;\ asm volatile ( \ \ "l.xor\t%3,%1,%2 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.sub\t%0,%1,%2 \n"\ "l.exths\t%0,%0 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t5 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.addi\t%3,r0,0x7fff \n"\ "l.addi\t%4,r0,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define add_i_OR32(var_out, var1, var2){\ volatile Word32 __aux1=0;\ volatile Word32 __aux2=var1;\ asm volatile ( \ \ "l.xori\t%3,%1,%2 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.addi\t%0,%1,%2 \n"\ "l.exths\t%0,%0 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t5 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.addi\t%3,r0,0x7fff \n"\ "l.addi\t%4,r0,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "i" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define div_s_OR32(var_out, var1, var2){\ Word32 __aux1=0;\ Word32 __aux2=2;\ asm volatile ( "l.addi\t%0,r0,0x0 \n"\ "l.ori\t%4,%1,0x0 \n"\ "l.addi\t%3,r0,0xffff \n"\ "l.addi\t%3,%3,0x1 \n"\ "l.sfltsi\t%3,0xf \n"\ "l.bnf\t8 \n"\ "l.slli\t%4,%4,0x1 \n"\ "l.sfges\t%4,%2 \n"\ "l.bnf\t-5 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.sub\t%4,%4,%2 \n"\ "l.j\t-8 \n"\ "l.addi\t%0,%0,0x1 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define shr_OR32(var_out, var1, var2){\ asm volatile ( "l.sra\t%0,%1,%2 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) );\ } #define shr_i_OR32(var_out, var1, var2){\ asm volatile ( "l.srai\t%0,%1,%2 \n"\ : "=r" (var_out) \

Page 166: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 165

Pedro Mota | Pedro Santos

: "r" (var1) , "i" (var2) );\ } #define L_shr_OR32(L_var_out, L_var1, var2){\ Word32 __aux1 = 0x1f;\ asm volatile ( "l.sfgtsi\t%2,0x1f \n"\ "l.cmov\t%3,%3,%2 \n"\ "l.sra\t%0,%1,%3 \n"\ : "=r" (L_var_out) \ : "r" (L_var1) , "r" (var2) , "r" (__aux1));\ } #define L_shr_i_OR32(L_var_out, L_var1, var2){\ asm volatile ( "l.srai\t%0,%1,%2 \n"\ : "=r" (L_var_out) \ : "r" (L_var1) , "i" (var2) );\ } #define L_add_OR32(var_out, var1, var2){\ Word32 __aux1=0;\ Word32 __aux2=var1;\ asm volatile ( "l.xor\t%3,%1,%2 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.add\t%0,%1,%2 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t6 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define L_add_i_OR32(var_out, var1, var2){\ volatile Word32 __aux1=0;\ volatile Word32 __aux2=var1;\ asm volatile ( "l.xori\t%3,%1,%2 \n"\ "l.sfltsi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.addi\t%0,%1,%2 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t6 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "i" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define L_sub_OR32(var_out, var1, var2){\ volatile Word32 __aux1=0;\ volatile Word32 __aux2=var1;\ asm volatile ( "l.xor\t%3,%1,%2 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t10 \n"\ "l.sub\t%0,%1,%2 \n"\ "l.xor\t%3,%4,%0 \n"\ "l.sfgesi\t%3,0x0 \n"\ "l.bf\t6 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2));\ } #define L_shl_OR32(L_var_out, L_var1, var2){\ Word32 __aux1=0x3fffffff;\ Word32 __aux2=0xc0000000;\

Page 167: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 166

Pedro Mota | Pedro Santos

Word32 __aux3;\ asm volatile ( "l.sflesi\t%2,0x0 \n"\ "l.bf\t20 \n"\ "l.cmov\t%0,%1,%1 \n"\ "l.movhi\t%3,0x3fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0xc000 \n"\ "l.cmov\t%5,%2,%2 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t8 \n"\ "l.sfles\t%0,%4 \n"\ "l.bf\t6 \n"\ "l.addi\t%5,%5,0xffff \n"\ "l.sfgtsi\t%5,0x0 \n"\ "l.bf\t-6 \n"\ "l.slli\t%0,%0,0x1 \n"\ "l.j\t6 \n"\ "l.sfgesi\t%0,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff \n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (L_var_out) \ : "r" (L_var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2) , "r" (__aux3));\ } #define L_shl_i_OR32(L_var_out, L_var1, var2) L_shl_OR32(L_var_out, L_var1, var2) #define L_shl_round_OR32(var_out, L_var1, var2){\ Word32 __aux1=0x3fffffff;\ Word32 __aux2=0xc0000000;\ Word32 __aux3;\ asm volatile ( "l.sflesi\t%2,0x0 \n"\ "l.bf\t20 \n"\ "l.cmov\t%0,%1,%1 \n"\ "l.movhi\t%3,0x3fff \n"\ "l.ori\t%3,%3,0xffff\n"\ "l.movhi\t%4,0xc000 \n"\ "l.cmov\t%5,%2,%2 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t8 \n"\ "l.sfles\t%0,%4 \n"\ "l.bf\t6 \n"\ "l.addi\t%5,%5,0xffff\n"\ "l.sfgtsi\t%5,0x0 \n"\ "l.bf\t-6 \n"\ "l.slli\t%0,%0,0x1\n"\ "l.j\t6 \n"\ "l.sfgesi\t%0,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff\n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ \ "l.srai\t%0,%0,0xf\n"\ "l.addi\t%0,%0,0x1\n"\ "l.srai\t%0,%0,0x1\n"\ "l.sfgtsi\t%0,0x7fff\n"\ "l.bnf\t3 \n"\ "l.nop\t0x0 \n"\ "l.addi\t%0,r0,0x7fff\n"\ : "=r" (var_out) \ : "r" (L_var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2) , "r" (__aux3));\ } #define L_shl_i_round_OR32(var_out, L_var1, var2) L_shl_round_OR32(var_out, L_var1, var2) #define L_shl_extract_h_OR32(var_out, L_var1, var2){\ Word32 __aux1=0x3fffffff;\ Word32 __aux2=0xc0000000;\ Word32 __aux3;\ asm volatile ( "l.sflesi\t%2,0x0 \n"\ "l.bf\t20 \n"\ "l.cmov\t%0,%1,%1 \n"\ "l.movhi\t%3,0x3fff \n"\

Page 168: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 167

Pedro Mota | Pedro Santos

"l.ori\t%3,%3,0xffff\n"\ "l.movhi\t%4,0xc000 \n"\ "l.cmov\t%5,%2,%2 \n"\ "l.sfges\t%0,%3 \n"\ "l.bf\t8 \n"\ "l.sfles\t%0,%4 \n"\ "l.bf\t6 \n"\ "l.addi\t%5,%5,0xffff\n"\ "l.sfgtsi\t%5,0x0 \n"\ "l.bf\t-6 \n"\ "l.slli\t%0,%0,0x1\n"\ "l.j\t6 \n"\ "l.sfgesi\t%0,0x0 \n"\ "l.movhi\t%3,0x7fff \n"\ "l.ori\t%3,%3,0xffff\n"\ "l.movhi\t%4,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ \ "l.srai\t%0,%0,0x10\n"\ : "=r" (var_out) \ : "r" (L_var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2) , "r" (__aux3));\ } #define L_shl_i_extract_h_OR32(var_out, L_var1, var2) L_shl_extract_h_OR32(var_out, L_var1, var2) #define L_shl_n_sat_OR32(var_out, L_var1, var2){\ asm volatile ( "l.sll\t%0,%1,%2 \n"\ : "=r" (var_out) \ : "r" (L_var1) , "r" (var2));\ } #define L_shl_n_sat_extract_h_OR32(var_out, L_var1, var2){\ asm volatile ( "l.sll\t%0,%1,%2 \n"\ "l.srai\t%0,%0,0x10 \n"\ : "=r" (var_out) \ : "r" (L_var1) , "r" (var2));\ } #define L_shl_n_sat_round_OR32(var_out, L_var1, var2){\ asm volatile ( "l.sll\t%0,%1,%2 \n"\ \ "l.srai\t%0,%0,0xf \n"\ "l.addi\t%0,%0,0x1 \n"\ "l.srai\t%0,%0,0x1 \n"\ "l.sfgtsi\t%0,0x7fff \n"\ "l.bnf\t3 \n"\ "l.nop\t0x0 \n"\ "l.addi\t%0,r0,0x7fff \n"\ : "=r" (var_out) \ : "r" (L_var1) , "r" (var2));\ } #define shl_OR32(var_out, var1, var2){\ Word32 __aux1=0xf;\ Word32 __aux2;\ asm volatile ( "l.sfgtsi\t%2,0xf \n"\ "l.cmov\t%3,%3,%2 \n"\ "l.sll\t%0,%1,%3 \n"\ "l.sfgtsi\t%0,0x7fff \n"\ "l.bf\t3 \n"\ "l.sfltsi\t%0,0x8000 \n"\ "l.bnf\t5 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.addi\t%3,r0,0x7fff \n"\ "l.addi\t%4,r0,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) , "r" (__aux1) , "r" (__aux2) );\ } #define shl_i_OR32(var_out, var1, var2){\ Word32 __aux1;\ Word32 __aux2=0xffff8000;\ asm volatile ( "l.slli\t%0,%1,%2 \n"\ "l.sfgtsi\t%0,0x7fff \n"\

Page 169: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 168

Pedro Mota | Pedro Santos

"l.bf\t3 \n"\ "l.sfltsi\t%0,0x8000 \n"\ "l.bnf\t5 \n"\ "l.sfgesi\t%1,0x0 \n"\ "l.addi\t%3,r0,0x7fff \n"\ "l.addi\t%4,r0,0x8000 \n"\ "l.cmov\t%0,%3,%4 \n"\ : "=r" (var_out) \ : "r" (var1) , "i" (var2) , "r" (__aux1) , "r" (__aux2) );\ } #define shl_n_sat_OR32(var_out, var1, var2){\ asm volatile ( "l.sll\t%0,%1,%2 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (var2) );\ } #define shl_i_n_sat_OR32(var_out, var1, var2){\ asm volatile ( "l.slli\t%0,%1,%2 \n"\ : "=r" (var_out) \ : "r" (var1) , "i" (var2) );\ } #define norm_s_OR32(var_out, var1){\ Word32 __aux1;\ asm volatile ( "l.sfeqi\t%1,0x0 \n"\ "l.bf\t14 \n"\ "l.addi\t%0,r0,0x0 \n"\ "l.sfeqi\t%1,0xffff \n"\ "l.bf\t11 \n"\ "l.addi\t%0,r0,0xf \n"\ "l.cmov\t%2,%1,%1 \n"\ "l.sfltsi\t%1,0x0 \n"\ "l.bnf\t3 \n"\ "l.addi\t%0,r0,0xffff \n"\ "l.xori\t%2,%1,0xffff \n"\ "l.addi\t%0,%0,0x1 \n"\ "l.sfltsi\t%2,0x4000 \n"\ "l.bf\t-2 \n"\ "l.slli\t%2,%2,0x1 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (__aux1) );\ } #define norm_l_OR32(var_out, var1){\ Word32 __aux1;\ Word32 __aux2=0x40000000;\ asm volatile ( "l.movhi\t%3,0x4000 \n"\ "l.sfeqi\t%1,0x0 \n"\ "l.bf\t14 \n"\ "l.addi\t%0,r0,0x0 \n"\ "l.sfeqi\t%1,0xffff \n"\ "l.bf\t11 \n"\ "l.addi\t%0,r0,0x1f \n"\ "l.cmov\t%2,%1,%1 \n"\ "l.sfltsi\t%1,0x0 \n"\ "l.bnf\t3 \n"\ "l.addi\t%0,r0,0xffff \n"\ "l.xori\t%2,%1,0xffff \n"\ "l.addi\t%0,%0,0x1 \n"\ "l.sflts\t%2,%3 \n"\ "l.bf\t-2 \n"\ "l.slli\t%2,%2,0x1 \n"\ : "=r" (var_out) \ : "r" (var1) , "r" (__aux1) , "r" (__aux2) );\ }

Page 170: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 169

Pedro Mota | Pedro Santos

Anexo 7: tt_ssram.v ///////////////////////////////////////////////////////////////////// //// //// //// OpenCores Memory Controller Testbench //// //// SSRAM memory devices tests //// //// This file is being included by the main testbench //// //// //// //// Author: Richard Herveille //// //// [email protected] //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2001, 2002 Richard Herveille //// //// [email protected] //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer.//// //// //// //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// //// POSSIBILITY OF SUCH DAMAGE. //// //// //// ///////////////////////////////////////////////////////////////////// // CVS Log // // $Id: tst_ssram.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $ // // $Date: 2002/03/06 15:10:34 $ // $Revision: 1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: tst_ssram.v,v $ // Revision 1.1 2002/03/06 15:10:34 rherveille // Initial release // // //////////////////////////////// // SSRAM Sequential access test // // 1) Tests ssram sequential address access // 2) Tests page switch // 3) Test burst-action by filling memory backwards (high addresses first) task tst_ssram_seq; parameter MAX_CYC_DELAY = 1;//5; parameter MAX_STB_DELAY =1;//5; parameter SSRAM_TST_RUN = 8;//128; parameter [31:0] SSRAM_TST_STARTA = `SSRAM_LOC + (SSRAM_TST_RUN<<2); parameter [ 7:0] SSRAM_SEL = SSRAM_TST_STARTA[28:21]; integer n, k; reg [31:0] my_adr, dest_adr;

Page 171: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 170

Pedro Mota | Pedro Santos

reg [31:0] my_dat; reg [15:0] tmp0, tmp1; // SSRAM Mode Register bits reg [31:0] csc_data, tms_data; integer cyc_delay, stb_delay, bl; begin $display("\n\n --- SSRAM SEQUENTIAL ACCESS TEST ---\n\n"); // clear Wishbone-Master-model current-error-counter wbm.set_cur_err_cnt(0); csc_data = { 8'h00, // reserved SSRAM_SEL, // SEL 4'h0, // reserved 1'b0, // parity enabled 1'b0, // KRO, no meaning for ssram 1'b0, // BAS, no meaning for ssram 1'b0, // WP 2'b00, // MS, no meaning for ssram 2'b10, // BW == 32bit bus. Always for ssram (maybe hardwire ???) 3'b001, // MEM_TYPE == SDRAM 1'b1 // EN == chip select enabled }; // tms_data is unused for ssrams tms_data = { 32'hx }; // program chip select registers $display("\nProgramming SSRAM chip select register."); wbm.wb_write(0, 0, 32'h6000_0030, csc_data); // program cs4 config register (CSC4) $display("Programming SSRAM timing register."); wbm.wb_write(0, 0, 32'h6000_0034, tms_data); // program cs4 timing register (TMS4) // check written data wbm.wb_cmp(0, 0, 32'h6000_0030, csc_data); wbm.wb_cmp(0, 0, 32'h6000_0034, tms_data); cyc_delay = 0; stb_delay = 0; for (cyc_delay = 0; cyc_delay <= MAX_CYC_DELAY; cyc_delay = cyc_delay +1) for (stb_delay = 0; stb_delay <= MAX_STB_DELAY; stb_delay = stb_delay +1) for (bl = 1; bl <= 8 ; bl = bl +1) begin $display("\nSSRAM sequential test. BL = %d, CYC-delay = %d, STB-delay = ", bl, cyc_delay, stb_delay); // fill sdrams $display("Filling SSRAM memory..."); my_dat = 0; for (n=0; n < SSRAM_TST_RUN; n=n+1) begin my_adr = SSRAM_TST_STARTA + ( (SSRAM_TST_RUN -n -bl) <<2); for (k=0; k < bl; k=k+1) begin // fill destination backwards, but with linear bursts dest_adr = my_adr + (k<<2); tmp0 = ~dest_adr[15:0] + bl + cyc_delay + stb_delay;

Page 172: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 171

Pedro Mota | Pedro Santos

tmp1 = dest_adr[15:0] + bl + cyc_delay + stb_delay; my_dat = {tmp0, tmp1}; wbm.wb_write(cyc_delay, stb_delay, dest_adr, my_dat); $display (" time = %f operação de leitura e de teste no master 1 \n",$time); wbm.wb_cmp( cyc_delay, stb_delay, dest_adr, my_dat ) ; end end // read sdrams /* $display("Verifying SSRAM memory contents..."); my_dat = 0; for (n=0; n < SSRAM_TST_RUN; n=n+1) begin my_adr = n<<2; dest_adr = SSRAM_TST_STARTA + my_adr; tmp0 = ~dest_adr[15:0] + bl + cyc_delay + stb_delay; tmp1 = dest_adr[15:0] + bl + cyc_delay + stb_delay; my_dat = {tmp0, tmp1}; wbm.wb_cmp(cyc_delay, stb_delay, dest_adr, my_dat); end*/ end repeat(10) @(posedge wb_clk); //wait a while // show Wishbone-Master-model current-error-counter wbm.show_cur_err_cnt; end endtask // test_ssram_seq

Page 173: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 172

Pedro Mota | Pedro Santos

Anexo 8: bench.v ///////////////////////////////////////////////////////////////////// //// //// //// OpenCores Memory Controller Testbench //// //// Main testbench //// //// //// //// Author: Richard Herveille //// //// [email protected] //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2001 Richard Herveille //// //// [email protected] //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer.//// //// //// //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// //// POSSIBILITY OF SUCH DAMAGE. //// //// //// ///////////////////////////////////////////////////////////////////// // ToDo: // 1) add power-on configuration // 2) test SSRAM // 3) test synchronous devices ??? // // CVS Log // // $Id: bench.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $ // // $Date: 2002/03/06 15:10:34 $ // $Revision: 1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: bench.v,v $ // Revision 1.1 2002/03/06 15:10:34 rherveille // Initial release // // `include "timescale.v" `define SDRAM_ROWA_HI 12 // row address hi-bit `define SDRAM_COLA_HI 8 // column address hi-bit `define BA_MASK 32'h0000_00e0 // base address mask `define SDRAM1_LOC 32'h0400_0000 // location of sdram1 in address-space `define SDRAM2_LOC 32'h0800_0000 // location of sdram2 in address-space `define SRAM_LOC 32'h0C00_0000 // location of srams in address-space `define SSRAM_LOC 32'h1000_0000 // location of ssrams in address-space module bench_top();

Page 174: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 173

Pedro Mota | Pedro Santos

// // internal wires // reg wb_clk; reg mc_clk; reg wb_rst; wire [31:0] wb_dat_i, wb_dat_o; wire [31:0] wb_adr_o; wire wb_cyc_o, wb_stb_o; wire [ 3:0] wb_sel_o; wire wb_ack_i, wb_err_i, wb_rty_i; wire wb_mc_stb; wire [23:0] mc_adr_o; wire [31:0] mc_dq, mc_dq_o; wire [ 3:0] mc_dp, mc_dp_o, pbus_o, pbus_i; reg [ 3:0] set_par; wire [31:0] par_con; reg sel_par, sel_pbus; wire par_sdram_cs; wire mc_doe_o; wire [ 3:0] mc_dqm_o; wire mc_we_o, mc_oe_o; wire mc_ras_o, mc_cas_o, mc_cke_o; wire [ 7:0] mc_cs_o; wire mc_pad_oe; wire mc_adsc_o, mc_adv_o, mc_zz_o; // ssram connections wire ext_br, ext_bg; // // hookup modules // // hookup watch-dog counter watch_dog #(1024) wdog ( .clk(wb_clk), .cyc_i(wbm1_cyc_o), .ack_i(wbm1_ack_i), .adr_i(wb_adr_i) ); // hookup external bus-master model bm_model ext_bm( .br(ext_br), .bg(ext_bg), .chk(mc_pad_oe) ); // hookup ERR checker err_check err_chk(wb_err_i, sel_par); // hookup CSn checker cs_check cs_chec(mc_cs_o); // hookup memory controller mc_top dut ( // wishbone interface .clk_i(wb_clk), .rst_i(wb_rst), .wb_data_i(wb_dat_o), .wb_data_o(wb_dat_i), .wb_addr_i(wb_adr_o), .wb_sel_i(wb_sel_o), .wb_we_i(wb_we_o), .wb_cyc_i(wb_cyc_o), .wb_stb_i(wb_stb_o), .wb_ack_o(wb_ack_i), .wb_err_o(wb_err_i), // memory controller .susp_req_i(1'b0), .resume_req_i(1'b0), .suspended_o(), .poc_o(),

Page 175: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 174

Pedro Mota | Pedro Santos

.mc_clk_i(mc_clk), .mc_br_pad_i(ext_br), .mc_bg_pad_o(ext_bg), .mc_ack_pad_i(1'b0), .mc_addr_pad_o(mc_adr_o), .mc_data_pad_i(mc_dq), .mc_data_pad_o(mc_dq_o), .mc_dp_pad_i(pbus_i), // attach parity bus .mc_dp_pad_o(mc_dp_o), .mc_doe_pad_doe_o(mc_doe_o), .mc_dqm_pad_o(mc_dqm_o), .mc_oe_pad_o_(mc_oe_o), .mc_we_pad_o_(mc_we_o), .mc_cas_pad_o_(mc_cas_o), .mc_ras_pad_o_(mc_ras_o), .mc_cke_pad_o_(mc_cke_o), .mc_cs_pad_o_(mc_cs_o), .mc_sts_pad_i(1'b0), .mc_rp_pad_o_(), .mc_vpen_pad_o(), .mc_adsc_pad_o_(mc_adsc_o), .mc_adv_pad_o_(mc_adv_o), .mc_zz_pad_o(mc_zz_o), .mc_coe_pad_coe_o(mc_pad_oe) ); // assign memory controller stb_signal assign wb_mc_stb = wb_adr_o[31]; // generate output buffers for memory controller assign mc_dq = mc_doe_o ? mc_dq_o : 32'bz; assign mc_dp = mc_doe_o ? mc_dp_o : 4'bz; // hookup ssrams (CHIP SELECT 4) mt58l1my18d ssram0 ( .Dq( {par_con[24], par_con[16], mc_dq[31:16]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[3]), .Bwb_n(mc_dqm_o[2]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), // ?? .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); mt58l1my18d ssram1 ( .Dq( {par_con[8], par_con[0], mc_dq[15:0]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[1]), .Bwb_n(mc_dqm_o[0]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); // hookup sdrams (CHIP SELECT 3) mt48lc16m16a2 sdram0_3(

Page 176: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 175

Pedro Mota | Pedro Santos

.Dq(mc_dq[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_3( .Dq(mc_dq[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup sdrams (CHIP SELECT 2 or PARITY) assign pbus_o = sel_pbus ? (sel_par ? mc_dp : set_par) : mc_dq; assign par_con = {7'bz, pbus_o[3], 7'bz, pbus_o[2], 7'bz, pbus_o[1], 7'bz, pbus_o[0]}; assign pbus_i = {par_con[24], par_con[16], par_con[8], par_con[0]}; assign par_sdram_cs = sel_pbus ? mc_cs_o[3] : mc_cs_o[2]; mt48lc16m16a2 sdram0_2( .Dq(par_con[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_2( .Dq(par_con[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup asynchronous srams (CHIP SELECT 1) A8Kx8 asram0 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[31:24]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram1 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[23:16]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) );

Page 177: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 176

Pedro Mota | Pedro Santos

A8Kx8 asram2 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[15: 8]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram3 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[ 7: 0]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); // hookup wishbone master wb_master_model wbm( .clk(wb_clk), .rst(wb_rst), .adr(wb_adr_o), .din(wb_dat_i), .dout(wb_dat_o), .cyc(wb_cyc_o), .stb(wb_stb_o), .we(wb_we_o), .sel(wb_sel_o), .ack(wb_ack_i), .err(wb_err_i), .rty(wb_rty_i) ); // // testbench body // assign wb_rty_i = 1'b0; // no retries from memory controller // generate clock always #2.5 wb_clk <= ~wb_clk; always@(posedge wb_clk) // mc_clk <= #1 ~mc_clk; mc_clk <= #0 ~mc_clk; // initial statements initial begin wb_clk = 0; // start with low-level clock wb_rst = 1; // assert reset mc_clk = 0; sel_par = 1; // do not modify parity bits sel_pbus = 1; // use second SDRAMS set as parity sdrams repeat(20) @(posedge wb_clk); wb_rst = 0; // negate reset @(posedge wb_clk); run_tests; // show total errors detected wbm.show_tot_err_cnt; $stop; end ////////////////////// // // Internal tasks // task run_tests;

Page 178: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 177

Pedro Mota | Pedro Santos

begin prg_mc; // program memory controller BA-mask and CSR registers // force sdram0_3.Debug = 1'b1; // turn on SDRAM debug option force sdram0_3.Debug = 1'b0; // turn off SDRAM debug option /////////////// // SDRAM tests // tst_sdram_memfill; // test sdrams: Fill entire memory and verify // tst_sdram_parity; // test sdrams: Parity generation // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_sdram_rnd; // test sdrams: Fill-Verify, random access // tst_sdram_rmw_seq; // test sdrams: Read-Modify-Write test, sequential access // tst_sdram_rmw_rnd; // test sdrams: Read-Modify-Write test, random access // tst_sdram_blk_cpy1; // test sdrams: Perform block copy, different src and dest. address // tst_sdram_blk_cpy2; // test sdrams: Perform block copy, src and dest same address // tst_sdram_bytes; // test sdrams: Peform byte accesses ////////////////////////////// // ASYNCHRONOUS MEMORIES TEST // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back //////////////// // SSRAMS TESTS tst_ssram_seq; ////////////////////// // MULTI MEMORY TESTS // tst_blk_cpy1; // test block-copy: access sdrams + asrams // The next test (tst_blk_cyp2) is, saddly to say, useless. // It tests n-by-n situations for multiple SDRAMS, testing all possible settings for each SDRAM. // It is supposed to test the independence for each SDRAM chip-select. // However it is to time-consuming; it runs for about a month on an Athlon-XP 1800 system // tst_blk_cpy2; // test block-copy: access multiple sdrams ///////////////////////////// // EXTERNAL BUS MASTER TESTS // turn on external bus-master and rerun some tests // force ext_bm.on_off = 1'b1; // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back // tst_blk_cpy1; // test block-copy: access sdrams + asrams end endtask // run_tests task prg_mc; begin wbm.wb_write(0, 0, 32'h6000_0008, `BA_MASK); // program base address register wbm.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR // check written data wbm.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); end endtask //prg_mc

Page 179: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 178

Pedro Mota | Pedro Santos

//////////////////////////////// // Register test // task reg_test; begin end endtask // reg_test ///////////////////////// // include memory tests // // `include "tst_sdram.v" // `include "tst_asram.v" `include "tst_ssram.v" // `include "tst_multi_mem.v" endmodule

Page 180: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 179

Pedro Mota | Pedro Santos

Anexo 9: wb.vhd (descrição do master slave) -- Generated by PERL program wishbone.pl. Do not edit this file. -- -- For defines see wishbone.defines -- -- Generated Tue Jun 21 17:24:49 2005 -- -- Wishbone masters: -- wbm1 -- wbm2 -- -- Wishbone slaves: -- wbs1 -- baseadr 0x10000000 - size 0x00100000 -- baseadr 0x60000000 - size 0xffff -- baseadr 0x00000000 - size 0xffff ----------------------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; package intercon_package is function "and" ( l : std_logic_vector; r : std_logic) return std_logic_vector; end intercon_package; package body intercon_package is function "and" ( l : std_logic_vector; r : std_logic) return std_logic_vector is variable result : std_logic_vector(l'range); begin -- "and" for i in l'range loop result(i) := l(i) and r; end loop; -- i return result; end "and"; end intercon_package; library IEEE; use IEEE.std_logic_1164.all; entity trafic_supervision is generic ( priority : integer := 1; tot_priority : integer := 2); port ( bg : in std_logic; -- bus grant ce : in std_logic; -- clock enable trafic_limit : out std_logic; clk : in std_logic; reset : in std_logic); end trafic_supervision; architecture rtl of trafic_supervision is signal shreg : std_logic_vector(tot_priority-1 downto 0); signal cntr : integer range 0 to tot_priority; begin -- rtl -- purpose: holds information of usage of latest cycles -- type : sequential -- inputs : clk, reset, ce, bg -- outputs: shreg('left) sh_reg: process (clk) begin -- process shreg if clk'event and clk = '1' then -- rising clock edge

Page 181: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 180

Pedro Mota | Pedro Santos

if ce='1' then shreg <= shreg(tot_priority-2 downto 0) & bg; end if; end if; end process sh_reg; -- purpose: keeps track of used cycles -- type : sequential -- inputs : clk, reset, shreg('left), bg, ce -- outputs: trafic_limit counter: process (clk, reset) begin -- process counter if reset = '1' then -- asynchronous reset (active hi) cntr <= 0; trafic_limit <= '0'; elsif clk'event and clk = '1' then -- rising clock edge if ce='1' then if bg='1' and shreg(tot_priority-1)/='1' then cntr <= cntr + 1; if cntr=priority-1 then trafic_limit <= '1'; end if; elsif bg='0' and shreg(tot_priority-1)='1' then cntr <= cntr - 1; if cntr=priority then trafic_limit <= '0'; end if; end if; end if; end if; end process counter; end rtl; library IEEE; use IEEE.std_logic_1164.all; use work.intercon_package.all; entity intercon is port ( -- wishbone master port(s) -- wbm1 wbm1_dat_i : out std_logic_vector(31 downto 0); wbm1_ack_i : out std_logic; wbm1_err_i : out std_logic; wbm1_rty_i : out std_logic; wbm1_dat_o : in std_logic_vector(31 downto 0); wbm1_we_o : in std_logic; wbm1_sel_o : in std_logic_vector(3 downto 0); wbm1_adr_o : in std_logic_vector(31 downto 0); wbm1_cyc_o : in std_logic; wbm1_stb_o : in std_logic; -- wbm2 wbm2_dat_i : out std_logic_vector(31 downto 0); wbm2_ack_i : out std_logic; wbm2_err_i : out std_logic; wbm2_rty_i : out std_logic; wbm2_dat_o : in std_logic_vector(31 downto 0); wbm2_we_o : in std_logic; wbm2_sel_o : in std_logic_vector(3 downto 0); wbm2_adr_o : in std_logic_vector(31 downto 0); wbm2_cyc_o : in std_logic; wbm2_stb_o : in std_logic; -- wishbone slave port(s) -- wbs1 wbs1_dat_o : in std_logic_vector(31 downto 0); wbs1_ack_o : in std_logic; wbs1_err_o : in std_logic; wbs1_rty_o : in std_logic; wbs1_dat_i : out std_logic_vector(31 downto 0); wbs1_we_i : out std_logic; wbs1_sel_i : out std_logic_vector(3 downto 0); wbs1_adr_i : out std_logic_vector(31 downto 0); wbs1_cyc_i : out std_logic; wbs1_stb_i : out std_logic; -- clock and reset clk : in std_logic;

Page 182: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 181

Pedro Mota | Pedro Santos

reset : in std_logic); end intercon; architecture rtl of intercon is signal wbm1_bg : std_logic; -- bus grant signal wbm2_bg : std_logic; -- bus grant signal wbs1_ss : std_logic; -- slave select begin -- rtl arbiter_sharedbus: block signal wbm1_bg_1, wbm1_bg_2, wbm1_bg_q : std_logic; signal wbm2_bg_1, wbm2_bg_2, wbm2_bg_q : std_logic; signal wbm1_trafic_ctrl_limit : std_logic; signal wbm2_trafic_ctrl_limit : std_logic; signal ack, ce, idle :std_logic; begin -- arbiter ack <= wbs1_ack_o; trafic_supervision_1 : entity work.trafic_supervision generic map( priority => 5000, tot_priority => 10000) port map( bg => wbm1_bg, ce => ce, trafic_limit => wbm1_trafic_ctrl_limit, clk => clk, reset => reset); trafic_supervision_2 : entity work.trafic_supervision generic map( priority => 5000 , tot_priority => 10000) port map( bg => wbm2_bg, ce => ce, trafic_limit => wbm2_trafic_ctrl_limit, clk => clk, reset => reset); process(clk,reset) begin if reset='1' then wbm1_bg_q <= '0'; elsif clk'event and clk='1' then if wbm1_bg_q='0' then wbm1_bg_q <= wbm1_bg; elsif ack='1' then wbm1_bg_q <= '0'; end if; end if; end process; process(clk,reset) begin if reset='1' then wbm2_bg_q <= '0'; elsif clk'event and clk='1' then if wbm2_bg_q='0' then wbm2_bg_q <= wbm2_bg; elsif ack='1' then wbm2_bg_q <= '0'; end if; end if; end process; idle <= '1' when wbm1_bg_q='0' and wbm2_bg_q='0' else '0'; wbm1_bg_1 <= '1' when idle='1' and wbm1_cyc_o='1' and wbm1_trafic_ctrl_limit='0' else '0'; wbm2_bg_1 <= '1' when idle='1' and wbm2_cyc_o='1' and wbm2_trafic_ctrl_limit='0' and (wbm1_bg_1='0') else '0'; wbm1_bg_2 <= '1' when idle='1' and (wbm1_bg_1='0' and wbm2_bg_1='0') and wbm1_cyc_o='1' else '0'; wbm2_bg_2 <= '1' when idle='1' and (wbm1_bg_1='0' and wbm2_bg_1='0' and wbm1_bg_2='0') and wbm2_cyc_o='1' else '0'; wbm1_bg <= wbm1_bg_q or wbm1_bg_1 or wbm1_bg_2; wbm2_bg <= wbm2_bg_q or wbm2_bg_1 or wbm2_bg_2; ce <= wbm1_cyc_o or wbm2_cyc_o when idle='1' else '0'; end block arbiter_sharedbus;

Page 183: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 182

Pedro Mota | Pedro Santos

decoder:block signal adr : std_logic_vector(31 downto 0); begin adr <= (wbm1_adr_o and wbm1_bg) or (wbm2_adr_o and wbm2_bg); wbs1_ss <= '1' when adr(31 downto 20)="000100000000" else '1' when adr(31 downto 16)="0110000000000000" else '1' when adr(31 downto 16)="0000000000000000" else '0'; wbs1_adr_i <= adr(31 downto 0); end block decoder; mux: block signal cyc, stb, we, ack : std_logic; signal sel : std_logic_vector(3 downto 0); signal dat_m2s, dat_s2m : std_logic_vector(31 downto 0); begin cyc <= (wbm1_cyc_o and wbm1_bg) or (wbm2_cyc_o and wbm2_bg); wbs1_cyc_i <= wbs1_ss and cyc; stb <= (wbm1_stb_o and wbm1_bg) or (wbm2_stb_o and wbm2_bg); wbs1_stb_i <= stb; we <= (wbm1_we_o and wbm1_bg) or (wbm2_we_o and wbm2_bg); wbs1_we_i <= we; ack <= wbs1_ack_o; wbm1_ack_i <= ack and wbm1_bg; wbm2_ack_i <= ack and wbm2_bg; wbm1_rty_i <= wbs1_rty_o; wbm2_rty_i <= wbs1_rty_o; wbm1_err_i <= wbs1_err_o; wbm2_err_i <= wbs1_err_o; sel <= (wbm1_sel_o and wbm1_bg) or (wbm2_sel_o and wbm2_bg); wbs1_sel_i <= sel; dat_m2s <= (wbm1_dat_o and wbm1_bg) or (wbm2_dat_o and wbm2_bg); wbs1_dat_i <= dat_m2s; dat_s2m <= (wbs1_dat_o and wbs1_ss); wbm1_dat_i <= dat_s2m; wbm2_dat_i <= dat_s2m; end block mux; end rtl;

Page 184: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 183

Pedro Mota | Pedro Santos

Anexo 10: Wishone.defines (definições para a elaboração do master slave) # Generated by PERL program wishbone.pl. # File used as input for wishbone arbiter generation # Generated Wed Jun 22 01:23:19 2005 filename=wb intercon=intercon syscon=syscon target=xilinx hdl=vhdl signal_groups=0 tga_bits=2 tgc_bits=3 tgd_bits=0 rename_tga=bte rename_tgc=cti rename_tgd=tgd classic=000 endofburst=111 dat_size=32 adr_size=32 mux_type=andor interconnect=sharedbus master wbm1 type=rw lock_o=0 tga_o=0 tgc_o=0 tgd_o=0 err_i=1 rty_i=1 priority=30 end master wbm1 master wbm2 type=rw lock_o=0 tga_o=0 tgc_o=0 tgd_o=0 err_i=1 rty_i=1 priority=5 end master wbm2 master wbm3 type=rw lock_o=0 tga_o=0 tgc_o=0 tgd_o=0 err_i=1 rty_i=1 priority=20 end master wbm3 slave wbs1 type=rw adr_i_hi=31 adr_i_lo=0 tga_i=0 tgc_i=0 tgd_i=0 lock_i=0 err_o=1 rty_o=1 baseadr=0x00000000 size=0xffff baseadr1=0x60000000 size1=0xffff baseadr2=0x10000000 size2=0xfffff end slave wbs1

Page 185: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 184

Pedro Mota | Pedro Santos

Anexo 11: Modelo verilog da memória da Cypress /**************************************************************************************** * * File Name: CY7C1340G_PL_DCD.v * Version: 1.0 * Date: July 26th, 2004 * Model: BUS Functional * Simulator: Verilog-XL (CADENCE) * * * Queries: MPD Applications * Website: www.cypress.com/support * Company: Cypress Semiconductor * Part #: CY7C1340G (128K x 32) * * Description: Cypress 4Mb Synburst SRAM (Pipelined DCD) * * * Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY * WHATSOEVER AND CYPRESS SPECIFICALLY DISCLAIMS ANY * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR * A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. * * Copyright(c) Cypress Semiconductor, 2004 * All rights reserved * * Rev Date Changes * --- ---------- --------------------------------------- * 1.0 07/26/2004 - New Model * - New Testbench * - New test vector * ****************************************************************************************/ // DO NOT CHANGE THE TIMESCALE // MAKE SURE YOUR SIMULATOR USE "PS" RESOLUTION `timescale 1ns / 10ps // Timings for Different Speed Bins (sb): 250MHz, 225MHz, 200MHz, 167MHz, 133MHz, 100MHz `define sb250 `ifdef sb250 `define tCO 2.6 // Data Output Valid After CLK Rise `define tCYC 4.0 // Clock cycle time `define tCH 1.7 // Clock HIGH time `define tCL 1.7 // Clock LOW time `define tCHZ 2.6 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 2.6 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 2.6 // OE# LOW to Output Valid `define tAS 1.2 // Address Set-up Before CLK Rise `define tADS 1.2 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.2 // ADV# Set-up Before CLK Rise `define tWES 1.2 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.2 // Data Input Set-up Before CLK Rise `define tCES 1.2 // Chip Enable Set-up `define tAH 0.3 // Address Hold After CLK Rise `define tADH 0.3 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.3 // ADV# Hold After CLK Rise `define tWEH 0.3 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.3 // Data Input Hold After CLK Rise `define tCEH 0.3 // Chip Enable Hold After CLK Rise `endif `ifdef sb225 `define tCO 2.6 // Data Output Valid After CLK Rise `define tCYC 4.4 // Clock cycle time `define tCH 2.0 // Clock HIGH time

Page 186: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 185

Pedro Mota | Pedro Santos

`define tCL 2.0 // Clock LOW time `define tCHZ 2.6 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 2.6 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 2.6 // OE# LOW to Output Valid `define tAS 1.2 // Address Set-up Before CLK Rise `define tADS 1.2 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.2 // ADV# Set-up Before CLK Rise `define tWES 1.2 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.2 // Data Input Set-up Before CLK Rise `define tCES 1.2 // Chip Enable Set-up `define tAH 0.5 // Address Hold After CLK Rise `define tADH 0.5 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.5 // ADV# Hold After CLK Rise `define tWEH 0.5 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.5 // Data Input Hold After CLK Rise `define tCEH 0.5 // Chip Enable Hold After CLK Rise `endif `ifdef sb200 `define tCO 2.8 // Data Output Valid After CLK Rise `define tCYC 5.0 // Clock cycle time `define tCH 2.0 // Clock HIGH time `define tCL 2.0 // Clock LOW time `define tCHZ 2.8 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 2.8 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 2.8 // OE# LOW to Output Valid `define tAS 1.2 // Address Set-up Before CLK Rise `define tADS 1.2 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.2 // ADV# Set-up Before CLK Rise `define tWES 1.2 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.2 // Data Input Set-up Before CLK Rise `define tCES 1.2 // Chip Enable Set-up `define tAH 0.5 // Address Hold After CLK Rise `define tADH 0.5 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.5 // ADV# Hold After CLK Rise `define tWEH 0.5 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.5 // Data Input Hold After CLK Rise `define tCEH 0.5 // Chip Enable Hold After CLK Rise `endif `ifdef sb167 `define tCO 3.5 // Data Output Valid After CLK Rise `define tCYC 6.0 // Clock cycle time `define tCH 2.5 // Clock HIGH time `define tCL 2.5 // Clock LOW time `define tCHZ 3.5 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 3.5 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 3.5 // OE# LOW to Output Valid `define tAS 1.5 // Address Set-up Before CLK Rise `define tADS 1.5 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.5 // ADV# Set-up Before CLK Rise `define tWES 1.5 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.5 // Data Input Set-up Before CLK Rise `define tCES 1.5 // Chip Enable Set-up `define tAH 0.5 // Address Hold After CLK Rise `define tADH 0.5 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.5 // ADV# Hold After CLK Rise `define tWEH 0.5 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.5 // Data Input Hold After CLK Rise `define tCEH 0.5 // Chip Enable Hold After CLK Rise

Page 187: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 186

Pedro Mota | Pedro Santos

`endif `ifdef sb133 `define tCO 4.0 // Data Output Valid After CLK Rise `define tCYC 7.5 // Clock cycle time `define tCH 3.0 // Clock HIGH time `define tCL 3.0 // Clock LOW time `define tCHZ 4.0 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 4.0 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 4.0 // OE# LOW to Output Valid `define tAS 1.5 // Address Set-up Before CLK Rise `define tADS 1.5 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.5 // ADV# Set-up Before CLK Rise `define tWES 1.5 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.5 // Data Input Set-up Before CLK Rise `define tCES 1.5 // Chip Enable Set-up `define tAH 0.5 // Address Hold After CLK Rise `define tADH 0.5 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.5 // ADV# Hold After CLK Rise `define tWEH 0.5 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.5 // Data Input Hold After CLK Rise `define tCEH 0.5 // Chip Enable Hold After CLK Rise `endif `ifdef sb100 `define tCO 4.5 // Data Output Valid After CLK Rise `define tCYC 10.0 // Clock cycle time `define tCH 3.5 // Clock HIGH time `define tCL 3.5 // Clock LOW time `define tCHZ 4.5 // Clock to High-Z `define tCLZ 0.0 // Clock to Low-Z `define tOEHZ 4.5 // OE# HIGH to Output High-Z `define tOELZ 0.0 // OE# LOW to Output Low-Z `define tOEV 4.5 // OE# LOW to Output Valid `define tAS 1.5 // Address Set-up Before CLK Rise `define tADS 1.5 // ADSC#, ADSP# Set-up Before CLK Rise `define tADVS 1.5 // ADV# Set-up Before CLK Rise `define tWES 1.5 // BWx#, GW#, BWE# Set-up Before CLK Rise `define tDS 1.5 // Data Input Set-up Before CLK Rise `define tCES 1.5 // Chip Enable Set-up `define tAH 0.5 // Address Hold After CLK Rise `define tADH 0.5 // ADSC#, ADSP# Hold After CLK Rise `define tADVH 0.5 // ADV# Hold After CLK Rise `define tWEH 0.5 // BWx#, GW#, BWE# Hold After CLK Rise `define tDH 0.5 // Data Input Hold After CLK Rise `define tCEH 0.5 // Chip Enable Hold After CLK Rise `endif module CY7C1340G_PLDCD (ZZ, Mode, ADDR, GW_N, BWE_N, BWd_N, BWc_N, BWb_N, BWa_N, CE1_N, CE2, CE3_N, ADSP_N, ADSC_N, ADV_N, OE_N, DQ, CLK); parameter addr_bits = 17; // 17 bits parameter data_bits = 32; // 32 bits parameter mem_sizes = 131072; // 128K inout [(data_bits - 1) : 0] DQ; // Data IO input [(addr_bits - 1) : 0] ADDR; // ADDRess input Mode; // Burst Mode input ADV_N; // Synchronous ADDRess Advance input CLK; // Clock input ADSC_N; // Synchronous ADDRess Status Controller input ADSP_N; // Synchronous ADDRess Status Processor

Page 188: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 187

Pedro Mota | Pedro Santos

input BWa_N; // Synchronous Byte Write Enables input BWb_N; // Synchronous Byte Write Enables input BWc_N; // Synchronous Byte Write Enables input BWd_N; // Synchronous Byte Write Enables input BWE_N; // Byte Write Enable input GW_N; // Global Write input CE1_N; // Synchronous Chip Enable input CE2; // Synchronous Chip Enable input CE3_N; // Synchronous Chip Enable input OE_N; // Output Enable input ZZ; // Snooze Mode reg [((data_bits / 4) - 1) : 0] bank0 [0 : mem_sizes]; // Memory Bank 0 reg [((data_bits / 4) - 1) : 0] bank1 [0 : mem_sizes]; // Memory Bank 1 reg [((data_bits / 4) - 1) : 0] bank2 [0 : mem_sizes]; // Memory Bank 2 reg [((data_bits / 4) - 1) : 0] bank3 [0 : mem_sizes]; // Memory Bank 3 reg [(data_bits - 1) : 0] din; // Data In reg [(data_bits - 1) : 0] dout; // Data Out reg [(addr_bits - 1) : 0] addr_reg_in; // ADDRess Register In reg [(addr_bits - 1) : 0] addr_reg_read; // ADDRess Register for Read reg [(addr_bits - 1) : 0] addr_reg_write; // ADDRess Register for Write reg [1 : 0] bcount; // 2-bit Burst Counter reg [1 : 0] first_addr; // 2-bit Burst Counter reg ce_reg; reg Read_reg; reg Read_reg_o; reg WrN_reg; reg ADSP_N_o; reg pipe_reg; reg bwa_reg; reg bwb_reg; reg bwc_reg; reg bwd_reg; reg Sys_clk; reg test; reg pcsr_write; reg ctlr_write; reg latch_addr_current; reg latch_addr_old; wire ce = (~CE1_N & CE2 & ~CE3_N); wire Write_n = ~(((~BWa_N | ~BWb_N | ~BWc_N | ~BWd_N) & ~BWE_N) | ~GW_N ) ; wire Read = (((BWa_N & BWb_N & BWc_N & BWd_N) & ~BWE_N) | (GW_N & BWE_N) | (~ADSP_N & ce)) ; wire bwa_n = ~(~Write_n & (~GW_N | (~BWE_N & ~BWa_N ))); wire bwb_n = ~(~Write_n & (~GW_N | (~BWE_N & ~BWb_N ))); wire bwc_n = ~(~Write_n & (~GW_N | (~BWE_N & ~BWc_N ))); wire bwd_n = ~(~Write_n & (~GW_N | (~BWE_N & ~BWd_N ))); wire latch_addr = (~ADSC_N | (~ADSP_N & ~CE1_N)); wire #`tOEHZ OeN_HZ = OE_N ? 1 : 0; wire #`tOEV OeN_DataValid = ~OE_N ? 0 : 1; wire OeN_efct = ~OE_N ? OeN_DataValid : OeN_HZ; wire #`tCHZ WR_HZ = WrN_reg ? 1 : 0; wire #`tCLZ WR_LZ = ~WrN_reg ? 0 : 1; wire WR_efct = ~WrN_reg ? WR_LZ : WR_HZ; wire #`tCHZ CE_HZ = ~pipe_reg ? 0 : 1 ; wire #`tCLZ CE_LZ = pipe_reg ? 1 : 0 ;

Page 189: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 188

Pedro Mota | Pedro Santos

wire Pipe_efct = pipe_reg ? CE_LZ : CE_HZ ; wire #`tCHZ RD_HZ = ~Read_reg_o ? 0 : 1 ; wire #`tCLZ RD_LZ = Read_reg_o ? 1 : 0 ; wire RD_efct = Read_reg_o ? CE_LZ : CE_HZ ; // Initialize initial begin ce_reg = 1'b0; pipe_reg = 1'b0; Sys_clk = 1'b0; $timeformat (-9, 1, " ns", 10); // Format time unit $readmemh("banco0.mem",bank0); $readmemh("banco1.mem",bank1); $readmemh("banco2.mem",bank2); $readmemh("banco3.mem",bank3); end // System Clock Decode always begin @ (posedge CLK) begin Sys_clk = ~ZZ; end @ (negedge CLK) begin Sys_clk = 1'b0; end end always @ (posedge Sys_clk) begin // Read Register if (~Write_n) Read_reg_o = 1'b0; else Read_reg_o = Read_reg; if (~Write_n) Read_reg = 1'b0; else Read_reg = Read; if (Read_reg == 1'b1) begin pcsr_write = 1'b0; ctlr_write = 1'b0; end // Write Register if (Read_reg_o == 1'b1) WrN_reg = 1'b1; else WrN_reg = Write_n; latch_addr_old = latch_addr_current; latch_addr_current = latch_addr; if (latch_addr_old == 1'b1 & ~Write_n & ADSP_N_o == 1'b0) pcsr_write = 1'b1; //Ctlr Write = 0; Pcsr Write = 1; else if (latch_addr_current == 1'b1 & ~Write_n & ADSP_N & ~ADSC_N) ctlr_write = 1'b1; //Ctlr Write = 0; Pcsr Write = 1; // ADDRess Register if (latch_addr) begin addr_reg_in = ADDR; bcount = ADDR [1 : 0]; first_addr = ADDR [1 : 0]; end // ADSP_N Previous-Cycle Register ADSP_N_o <= ADSP_N; // Binary Counter and Logic if (~Mode & ~ADV_N & ~latch_addr) // Linear Burst bcount = (bcount + 1); // Advance Counter

Page 190: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 189

Pedro Mota | Pedro Santos

else if (Mode & ~ADV_N & ~latch_addr) // Interleaved Burst begin if (first_addr % 2 == 0) bcount = (bcount + 1); // Increment Counter else if (first_addr % 2 == 1) bcount = (bcount - 1); // Decrement Counter end // Read ADDRess addr_reg_read = addr_reg_write; // Write ADDRess addr_reg_write = {addr_reg_in [(addr_bits - 1) : 2], bcount[1], bcount[0]}; // Byte Write Register bwa_reg = ~bwa_n; bwb_reg = ~bwb_n; bwc_reg = ~bwc_n; bwd_reg = ~bwd_n; // Enable Register pipe_reg = ce_reg; // Enable Register if (latch_addr) ce_reg = ce; // Input Register if (ce_reg & (~bwa_n | ~bwb_n | ~bwc_n | ~bwd_n) & (pcsr_write | ctlr_write)) begin din = DQ; end // Byte Write Driver if (ce_reg & bwa_reg) begin bank0 [addr_reg_write] = din [ 7 : 0]; end if (ce_reg & bwb_reg) begin bank1 [addr_reg_write] = din [15 : 8]; end if (ce_reg & bwc_reg) begin bank2 [addr_reg_write] = din [23 : 16]; end if (ce_reg & bwd_reg) begin bank3 [addr_reg_write] = din [31 : 24]; end // Output Registers if (~Write_n | pipe_reg == 1'b0) dout [ 31 : 0] <= #`tCHZ 32'bZ; else if (Read_reg_o == 1'b1) begin dout [ 7 : 0] <= #`tCO bank0 [addr_reg_read]; dout [15 : 8] <= #`tCO bank1 [addr_reg_read]; dout [23 : 16] <= #`tCO bank2 [addr_reg_read]; dout [31 : 24] <= #`tCO bank3 [addr_reg_read]; end end // Output Buffers assign DQ = (~OE_N & ~ZZ & Pipe_efct & RD_efct & WR_efct) ? dout : 32'bz; // Timing Check specify $width (negedge CLK, `tCL); $width (posedge CLK, `tCH); $period (negedge CLK, `tCYC); $period (posedge CLK, `tCYC); $setuphold (posedge CLK, ADSP_N, `tADS, `tADH); $setuphold (posedge CLK, ADSC_N, `tADS, `tADH); $setuphold (posedge CLK, ADDR, `tAS, `tAH); $setuphold (posedge CLK, BWa_N, `tWES, `tWEH); $setuphold (posedge CLK, BWb_N, `tWES, `tWEH); $setuphold (posedge CLK, BWc_N, `tWES, `tWEH);

Page 191: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 190

Pedro Mota | Pedro Santos

$setuphold (posedge CLK, BWd_N, `tWES, `tWEH); $setuphold (posedge CLK, BWE_N, `tWES, `tWEH); $setuphold (posedge CLK, GW_N, `tWES, `tWEH); $setuphold (posedge CLK, CE1_N, `tCES, `tCEH); $setuphold (posedge CLK, CE2, `tCES, `tCEH); $setuphold (posedge CLK, CE3_N, `tCES, `tCEH); $setuphold (posedge CLK, ADV_N, `tADVS, `tADVH); endspecify endmodule

Page 192: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 191

Pedro Mota | Pedro Santos

Anexo 12: Modelo verilog da memória da Micron /**************************************************************************************** * * File Name: MT58L1MY18D.V * Version: 1.3 * Date: March 8th, 1999 * Model: BUS Functional * Simulator: Model Technology * * Dependencies: None * * Author: Son P. Huynh * Email: [email protected] * Phone: (208) 368-3825 * Company: Micron Technology, Inc. * Part #: MT58L1MY18D (1Mb x 18) * * Description: This is Micron's Syncburst SRAM (Pipelined DCD) * * Limitation: * * Disclaimer: THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY * WHATSOEVER AND MICRON SPECIFICALLY DISCLAIMS ANY * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR * A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. * * Copyright (c) 1997 Micron Semiconductor Products, Inc. * All rights researved * * Rev Author Date Changes * --- ---------------------------- ---------- --------------------------------------- * 1.3 Son P. Huynh 208-368-3825 03/08/1999 Improve model functionality * Micron Technology, Inc. * ****************************************************************************************/ // DO NOT CHANGE THE TIMESCALE // MAKE SURE YOUR SIMULATOR USE "PS" RESOLUTION `timescale 1ns / 100ps module mt58l1my18d (Dq, Addr, Mode, Adv_n, Clk, Adsc_n, Adsp_n, Bwa_n, Bwb_n, Bwe_n, Gw_n, Ce_n, Ce2, Ce2_n, Oe_n, Zz); parameter addr_bits = 20; // 20 bits parameter data_bits = 18; // 18 bits parameter mem_sizes = 1048575; // 1 Mb parameter reg_delay = 0.1; // 100 ps parameter out_delay = 0.1; // 100 ps parameter tKQHZ = 3.5; // -6 device inout [(data_bits - 1) : 0] Dq; // Data IO input [(addr_bits - 1) : 0] Addr; // Address input Mode; // Burst Mode input Adv_n; // Synchronous Address Advance input Clk; // Clock input Adsc_n; // Synchronous Address Status Controller input Adsp_n; // Synchronous Address Status Processor input Bwa_n; // Synchronous Byte Write Enables input Bwb_n; // Synchronous Byte Write Enables input Bwe_n; // Byte Write Enable input Gw_n; // Global Write input Ce_n; // Synchronous Chip Enable input Ce2; // Synchronous Chip Enable input Ce2_n; // Synchronous Chip Enable input Oe_n; // Output Enable input Zz; // Snooze Mode reg [((data_bits / 2) - 1) : 0] bank0 [0 : mem_sizes]; // Memory Bank 0 reg [((data_bits / 2) - 1) : 0] bank1 [0 : mem_sizes]; // Memory Bank 1

Page 193: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 192

Pedro Mota | Pedro Santos

reg [(data_bits - 1) : 0] din; // Input Registers reg [(data_bits - 1) : 0] dout; // Output Registers reg [(addr_bits - 1) : 0] addr_reg_in; // Address Register In reg [(addr_bits - 1) : 0] addr_reg_read; // Address Register for Read Operation reg [1 : 0] bcount; // 2-bit Burst Counter reg ce_reg; reg pipe_reg; reg bwa_reg; reg bwb_reg; reg sys_clk; wire ce = (~Ce_n & ~Ce2_n & Ce2); wire bwa_n = (((Bwa_n | Bwe_n) & Gw_n) | (~Ce_n & ~Adsp_n)); wire bwb_n = (((Bwb_n | Bwe_n) & Gw_n) | (~Ce_n & ~Adsp_n)); wire clr = (~Adsc_n | (~Adsp_n & ~Ce_n)); wire [(addr_bits - 1) : 0] addr_reg_write; // Address Register for Write Operation wire baddr1; // Burst Address 1 wire baddr0; // Burst Address 0 // Initialize initial begin ce_reg = 1'b0; sys_clk = 1'b0; pipe_reg = 1'b0; $timeformat (-9, 1, " ns", 10); // Format time unit end task mem_fill; input x; integer a, n, x; begin a=0; for(n=0;n<x;n=n+1) begin bank0[n] = a; bank1[n] = a+1; a=a+2; end end endtask // System Clock always begin @ (posedge Clk) begin sys_clk = ~Zz; end @ (negedge Clk) begin sys_clk = 1'b0; end end always @ (posedge sys_clk) begin // Address Register if (clr) addr_reg_in <= Addr; addr_reg_read <= {addr_reg_in [(addr_bits - 1) : 2], baddr1, baddr0}; // Binary Counter and Logic if ( Mode & clr) bcount <= 0; // Interleaved Burst else if (~Mode & clr) bcount <= Addr [1 : 0]; // Linear Burst else if (~Adv_n & ~clr) bcount <= (bcount + 1); // Advance Counter // Byte Write Register bwa_reg <= ~bwa_n; bwb_reg <= ~bwb_n;

Page 194: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 193

Pedro Mota | Pedro Santos

// Enable Register if (clr) ce_reg <= ce; // Pipelined Enable pipe_reg <= ce_reg; end // Burst Address Decode assign addr_reg_write = {addr_reg_in [(addr_bits - 1) : 2], baddr1, baddr0}; assign baddr1 = Mode ? (bcount [1] ^ addr_reg_in [1]) : bcount [1]; assign baddr0 = Mode ? (bcount [0] ^ addr_reg_in [0]) : bcount [0]; // Write Driver always @ (posedge Clk) begin #reg_delay; if (ce_reg & bwa_reg) begin din [data_bits / 2 - 1 : 0] <= Dq [data_bits / 2 - 1 : 0]; bank0 [addr_reg_write] <= Dq [data_bits / 2 - 1 : 0]; end if (ce_reg & bwb_reg) begin din [data_bits - 1 : data_bits / 2] <= Dq [data_bits - 1 : data_bits / 2]; bank1 [addr_reg_write] <= Dq [data_bits - 1 : data_bits / 2]; end end // Output Registers always @ (posedge Clk) begin #out_delay; if (~(bwa_reg | bwb_reg)) begin dout [data_bits / 2 - 1 : 0] <= bank0 [addr_reg_read]; dout [data_bits - 1 : data_bits / 2] <= bank1 [addr_reg_read]; end else begin dout [data_bits - 1 : 0] <= {data_bits{1'bz}}; end end // Output Buffers assign #(tKQHZ) Dq = (~Oe_n & ~Zz & pipe_reg & ~(bwa_reg | bwb_reg)) ? dout : {data_bits{1'bz}}; // Timing Check (6 ns clock cycle / 166 MHz) // Please download latest datasheet from our Web site: // http://www.micron.com/mti specify specparam tKC = 6.0, // Clock - Clock cycle time tKH = 2.3, // Clock HIGH time tKL = 2.3, // Clock LOW time tAS = 1.5, // Setup Times - Address tADSS = 1.5, // Address Status tAAS = 1.5, // Address Advance tWS = 1.5, // Byte Write Enables tDS = 1.5, // Data-in tCES = 1.5, // Chip Enable tAH = 0.5, // Hold Times - Address tADSH = 0.5, // Address Status tAAH = 0.5, // Address Advance tWH = 0.5, // Byte Write Enables tDH = 0.5, // Data-in tCEH = 0.5; // Chip Enable $width (negedge Clk, tKL); $width (posedge Clk, tKH); $period (negedge Clk, tKC); $period (posedge Clk, tKC); $setuphold (posedge Clk, Adsp_n, tADSS, tADSH); $setuphold (posedge Clk, Adsc_n, tADSS, tADSH); $setuphold (posedge Clk, Addr, tAS, tAH); $setuphold (posedge Clk, Bwa_n, tWS, tWH); $setuphold (posedge Clk, Bwb_n, tWS, tWH); $setuphold (posedge Clk, Bwe_n, tWS, tWH); $setuphold (posedge Clk, Gw_n, tWS, tWH); $setuphold (posedge Clk, Ce_n, tCES, tCEH); $setuphold (posedge Clk, Ce2, tCES, tCEH); $setuphold (posedge Clk, Ce2_n, tCES, tCEH); $setuphold (posedge Clk, Adv_n, tAAS, tAAH); endspecify

Page 195: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 194

Pedro Mota | Pedro Santos

endmodule

Page 196: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 195

Pedro Mota | Pedro Santos

Anexo 13: bench1.v ///////////////////////////////////////////////////////////////////// //// //// //// OpenCores Memory Controller Testbench //// //// Main testbench //// //// //// //// Author: Richard Herveille //// //// [email protected] //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2001 Richard Herveille //// //// [email protected] //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer.//// //// //// //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// //// POSSIBILITY OF SUCH DAMAGE. //// //// //// ///////////////////////////////////////////////////////////////////// // ToDo: // 1) add power-on configuration // 2) test SSRAM // 3) test synchronous devices ??? // // CVS Log // // $Id: bench.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $ // // $Date: 2002/03/06 15:10:34 $ // $Revision: 1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: bench.v,v $ // Revision 1.1 2002/03/06 15:10:34 rherveille // Initial release // // `include "timescale.v" `define SDRAM_ROWA_HI 12 // row address hi-bit `define SDRAM_COLA_HI 8 // column address hi-bit `define BA_MASK 32'h0000_00e0 // base address mask `define SDRAM1_LOC 32'h0400_0000 // location of sdram1 in address-space `define SDRAM2_LOC 32'h0800_0000 // location of sdram2 in address-space `define SRAM_LOC 32'h0C00_0000 // location of srams in address-space `define SSRAM_LOC 32'h1000_0000 // location of ssrams in address-space module super_bench_top();

Page 197: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 196

Pedro Mota | Pedro Santos

// // internal wires // reg wb_clk; reg mc_clk; reg wb_rst; wire [31:0] wb_dat_i, wb_dat_o; wire [31:0] wb_adr_o; wire wb_cyc_o, wb_stb_o; wire [ 3:0] wb_sel_o; wire wb_ack_i, wb_err_i, wb_rty_i; wire wb_mc_stb; wire [23:0] mc_adr_o; wire [31:0] mc_dq, mc_dq_o; wire [ 3:0] mc_dp, mc_dp_o, pbus_o, pbus_i; reg [ 3:0] set_par; wire [31:0] par_con; reg sel_par, sel_pbus; wire par_sdram_cs; wire mc_doe_o; wire [ 3:0] mc_dqm_o; wire mc_we_o, mc_oe_o; wire mc_ras_o, mc_cas_o, mc_cke_o; wire [ 7:0] mc_cs_o; wire mc_pad_oe; wire mc_adsc_o, mc_adv_o, mc_zz_o; // ssram connections wire ext_br, ext_bg; /******************* wires needed to connect master1 to master/slave block*******/ wire [31:0] wbm1_dat_o; wire wbm1_ack_o ; wire wbm1_err_o ; wire wbm1_rty_o ; wire [31:0] wbm1_dat_i ; wire wbm1_we_i ; wire [3:0] wbm1_sel_i ; wire [31:0] wbm1_adr_i ; wire wbm1_cyc_i ; wire wbm1_stb_i ; /******************************************************************************/ /******************* wires needed to connect master2 to master/slave block*******/ wire [31:0] wbm2_dat_o; wire wbm2_ack_o ; wire wbm2_err_o ; wire wbm2_rty_o ; wire [31:0] wbm2_dat_i ; wire wbm2_we_i ; wire [3:0] wbm2_sel_i ; wire [31:0] wbm2_adr_i ; wire wbm2_cyc_i ; wire wbm2_stb_i ; real a ; /******************************************************************************/

Page 198: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 197

Pedro Mota | Pedro Santos

// // hookup modules // // hookup watch-dog counter /*watch_dog #(1024) wdog ( .clk(wb_clk), .cyc_i(wbm1_cyc_i), .ack_i(wbm1_ack_o), .adr_i(wbm1_adr_i) ); watch_dog #(1024) wdog2 ( .clk(wb_clk), .cyc_i(wbm2_cyc_i), .ack_i(wbm2_ack_o), .adr_i(wbm2_adr_i) );*/ // hookup external bus-master model bm_model ext_bm( .br(ext_br), .bg(ext_bg), .chk(mc_pad_oe) ); // hookup ERR checker err_check err_chk(wbm1_err_o, sel_par); // hookup CSn checker cs_check cs_chec(mc_cs_o); intercon master_slave( /* -- wishbone master port(s) -- wbm1*/ .wbm1_dat_i(wbm1_dat_o) , .wbm1_ack_i(wbm1_ack_o) , .wbm1_err_i(wbm1_err_o) , //.wbm1_rty_i() , .wbm1_dat_o(wbm1_dat_i) , .wbm1_we_o(wbm1_we_i) , .wbm1_sel_o(wbm1_sel_i) , .wbm1_adr_o(wbm1_adr_i), .wbm1_cyc_o(wbm1_cyc_i), .wbm1_stb_o(wbm1_stb_i), /* -- wbm2 */ .wbm2_dat_i(wbm2_dat_o) , .wbm2_ack_i(wbm2_ack_o) , .wbm2_err_i(wbm2_err_o) , //.wbm2_rty_i() , .wbm2_dat_o(wbm2_dat_i) , .wbm2_we_o(wbm2_we_i) , .wbm2_sel_o(wbm2_sel_i) , .wbm2_adr_o(wbm2_adr_i), .wbm2_cyc_o(wbm2_cyc_i), .wbm2_stb_o(wbm2_stb_i), /* wishbone slave port(s) wbs1 */ .wbs1_dat_o(wb_dat_i), .wbs1_ack_o(wb_ack_i) , .wbs1_err_o(wb_err_i) ,

Page 199: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 198

Pedro Mota | Pedro Santos

.wbs1_rty_o(1'b0) , .wbs1_dat_i(wb_dat_o), .wbs1_we_i (wb_we_o), .wbs1_sel_i(wb_sel_o), .wbs1_adr_i(wb_adr_o), .wbs1_cyc_i(wb_cyc_o), .wbs1_stb_i(wb_stb_o), .clk (wb_clk) , .reset (wb_rst ) ); // hookup memory controller mc_top dut ( // wishbone interface .clk_i(wb_clk), .rst_i(wb_rst), .wb_data_i(wb_dat_o), .wb_data_o(wb_dat_i), .wb_addr_i(wb_adr_o), .wb_sel_i(wb_sel_o), .wb_we_i(wb_we_o), .wb_cyc_i(wb_cyc_o), .wb_stb_i(wb_stb_o), .wb_ack_o(wb_ack_i), .wb_err_o(wb_err_i), // memory controller .susp_req_i(1'b0), .resume_req_i(1'b0), .suspended_o(), .poc_o(), .mc_clk_i(mc_clk), .mc_br_pad_i(ext_br), .mc_bg_pad_o(ext_bg), .mc_ack_pad_i(1'b0), .mc_addr_pad_o(mc_adr_o), .mc_data_pad_i(mc_dq), .mc_data_pad_o(mc_dq_o), .mc_dp_pad_i(pbus_i), // attach parity bus .mc_dp_pad_o(mc_dp_o), .mc_doe_pad_doe_o(mc_doe_o), .mc_dqm_pad_o(mc_dqm_o), .mc_oe_pad_o_(mc_oe_o), .mc_we_pad_o_(mc_we_o), .mc_cas_pad_o_(mc_cas_o), .mc_ras_pad_o_(mc_ras_o), .mc_cke_pad_o_(mc_cke_o), .mc_cs_pad_o_(mc_cs_o), .mc_sts_pad_i(1'b0), .mc_rp_pad_o_(), .mc_vpen_pad_o(), .mc_adsc_pad_o_(mc_adsc_o), .mc_adv_pad_o_(mc_adv_o), .mc_zz_pad_o(mc_zz_o), .mc_coe_pad_coe_o(mc_pad_oe) ); // assign memory controller stb_signal assign wb_mc_stb = wb_adr_o[31]; // generate output buffers for memory controller assign mc_dq = mc_doe_o ? mc_dq_o : 32'bz; assign mc_dp = mc_doe_o ? mc_dp_o : 4'bz; // hookup ssrams (CHIP SELECT 4) mt58l1my18d ssram0 ( .Dq( {par_con[24], par_con[16], mc_dq[31:16]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o),

Page 200: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 199

Pedro Mota | Pedro Santos

.Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[3]), .Bwb_n(mc_dqm_o[2]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), // ?? .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); mt58l1my18d ssram1 ( .Dq( {par_con[8], par_con[0], mc_dq[15:0]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[1]), .Bwb_n(mc_dqm_o[0]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); // hookup sdrams (CHIP SELECT 3) mt48lc16m16a2 sdram0_3( .Dq(mc_dq[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_3( .Dq(mc_dq[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup sdrams (CHIP SELECT 2 or PARITY) assign pbus_o = sel_pbus ? (sel_par ? mc_dp : set_par) : mc_dq; assign par_con = {7'bz, pbus_o[3], 7'bz, pbus_o[2], 7'bz, pbus_o[1], 7'bz, pbus_o[0]}; assign pbus_i = {par_con[24], par_con[16], par_con[8], par_con[0]}; assign par_sdram_cs = sel_pbus ? mc_cs_o[3] : mc_cs_o[2]; mt48lc16m16a2 sdram0_2( .Dq(par_con[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs),

Page 201: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 200

Pedro Mota | Pedro Santos

.Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_2( .Dq(par_con[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup asynchronous srams (CHIP SELECT 1) A8Kx8 asram0 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[31:24]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram1 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[23:16]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram2 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[15: 8]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram3 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[ 7: 0]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); /* .wbm1_dat_i(wbm1_dat_o) , .wbm1_ack_i(wbm1_ack_o) , .wbm1_err_i(wbm1_err_o) , .wbm1_rty_i(wbm1_rty_o) , .wbm1_dat_o(1'b0) , .wbm1_we_o(wbm1_we_i) , .wbm1_sel_o(wbm1_sel_i) , .wbm1_adr_o(wbm1_adr_i), .wbm1_cyc_o(wbm1_cyc_i), .wbm1_stb_o(wbm1_stb_i), */ // hookup wishbone master wb_master_model wbm( .clk(wb_clk), .rst(wb_rst), .adr(wbm1_adr_i), .din(wbm1_dat_o), .dout(wbm1_dat_i), .cyc(wbm1_cyc_i), .stb(wbm1_stb_i),

Page 202: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 201

Pedro Mota | Pedro Santos

.we(wbm1_we_i), .sel(wbm1_sel_i), .ack(wbm1_ack_o), .err(wbm1_err_o), .rty(1'b0) ); /* wire [31:0] wbm1_dat_o wire wbm1_ack_o ; wire wbm1_err_o ; wire wbm1_rty_o ; wire [31:0] wbm1_dat_i ; wire wbm1_we_i ; wire [3:0] wbm1_sel_i ; wire [31:0] wbm1_adr_i ; wire wbm1_cyc_i ; wire wbm1_stb_i ; */ /* --------------------------------------- master 2 -----------------------*/ wb_master_model wbm2( .clk(wb_clk), .rst(wb_rst), .adr(wbm2_adr_i), .din(wbm2_dat_o), .dout(wbm2_dat_i), .cyc(wbm2_cyc_i), .stb(wbm2_stb_i), .we(wbm2_we_i), .sel(wbm2_sel_i), .ack(wbm2_ack_o), .err(wbm2_err_o), .rty(1'b0) ); // // testbench body // assign wb_rty_i = 1'b0; // no retries from memory controller // generate clock always #2.5 wb_clk <= ~wb_clk; always@(posedge wb_clk) // mc_clk <= #1 ~mc_clk; mc_clk <= #0 ~mc_clk; // initial statements // testbench original!!!!! initial begin wb_clk = 0; // start with low-level clock wb_rst = 1; // assert reset mc_clk = 0;

Page 203: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 202

Pedro Mota | Pedro Santos

sel_par = 1; // do not modify parity bits sel_pbus = 1; // use second SDRAMS set as parity sdrams repeat(20) @(posedge wb_clk); wb_rst = 0; // negate reset #400 @(posedge wb_clk); //run_tests; a=0; while (1 && a < 2000) begin $display (" Escrita do master 1 \n"); wbm.wb_write(20, 10, 32'h6000_0008, `BA_MASK); // program base address register $display (" leitura e comparação do master 2\n"); wbm2.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); $display (" Escrita do master 2 \n"); wbm2.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR // check written data $display (" leitura e comparação do master 1\n"); wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); a=a+1; end // show total errors detected wbm.show_tot_err_cnt; wbm2.show_tot_err_cnt; $stop; end ////////////////////// // // Internal tasks // task run_tests; begin prg_mc; // program memory controller BA-mask and CSR registers // force sdram0_3.Debug = 1'b1; // turn on SDRAM debug option force sdram0_3.Debug = 1'b0; // turn off SDRAM debug option /////////////// // SDRAM tests // tst_sdram_memfill; // test sdrams: Fill entire memory and verify // tst_sdram_parity; // test sdrams: Parity generation // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_sdram_rnd; // test sdrams: Fill-Verify, random access // tst_sdram_rmw_seq; // test sdrams: Read-Modify-Write test, sequential access // tst_sdram_rmw_rnd; // test sdrams: Read-Modify-Write test, random access // tst_sdram_blk_cpy1; // test sdrams: Perform block copy, different src and dest. address // tst_sdram_blk_cpy2; // test sdrams: Perform block copy, src and dest same address // tst_sdram_bytes; // test sdrams: Peform byte accesses ////////////////////////////// // ASYNCHRONOUS MEMORIES TEST // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back //////////////// // SSRAMS TESTS tst_ssram_seq; ////////////////////// // MULTI MEMORY TESTS // tst_blk_cpy1; // test block-copy: access sdrams + asrams

Page 204: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 203

Pedro Mota | Pedro Santos

// The next test (tst_blk_cyp2) is, saddly to say, useless. // It tests n-by-n situations for multiple SDRAMS, testing all possible settings for each SDRAM. // It is supposed to test the independence for each SDRAM chip-select. // However it is to time-consuming; it runs for about a month on an Athlon-XP 1800 system // tst_blk_cpy2; // test block-copy: access multiple sdrams ///////////////////////////// // EXTERNAL BUS MASTER TESTS // turn on external bus-master and rerun some tests // force ext_bm.on_off = 1'b1; // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back // tst_blk_cpy1; // test block-copy: access sdrams + asrams end endtask // run_tests task prg_mc; begin wbm.wb_write(20, 10, 32'h6000_0008, `BA_MASK); // program base address register wbm.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR a=1; // check written data wbm.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); end endtask //prg_mc //////////////////////////////// // Register test // task reg_test; begin end endtask // reg_test ///////////////////////// // include memory tests // // `include "tst_sdram.v" // `include "tst_asram.v" `include "tst_ssram.v" // `include "tst_multi_mem.v" endmodule

Page 205: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 204

Pedro Mota | Pedro Santos

Anexo 14: bench2.v ///////////////////////////////////////////////////////////////////// //// //// //// OpenCores Memory Controller Testbench //// //// Main testbench //// //// //// //// Author: Richard Herveille //// //// [email protected] //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2001 Richard Herveille //// //// [email protected] //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer.//// //// //// //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// //// POSSIBILITY OF SUCH DAMAGE. //// //// //// ///////////////////////////////////////////////////////////////////// // ToDo: // 1) add power-on configuration // 2) test SSRAM // 3) test synchronous devices ??? // // CVS Log // // $Id: bench.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $ // // $Date: 2002/03/06 15:10:34 $ // $Revision: 1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: bench.v,v $ // Revision 1.1 2002/03/06 15:10:34 rherveille // Initial release // // `include "timescale.v" `define SDRAM_ROWA_HI 12 // row address hi-bit `define SDRAM_COLA_HI 8 // column address hi-bit `define BA_MASK 32'h0000_00e0 // base address mask `define SDRAM1_LOC 32'h0400_0000 // location of sdram1 in address-space `define SDRAM2_LOC 32'h0800_0000 // location of sdram2 in address-space `define SRAM_LOC 32'h0C00_0000 // location of srams in address-space `define SSRAM_LOC 32'h1000_0000 // location of ssrams in address-space

Page 206: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 205

Pedro Mota | Pedro Santos

module SSRAM_PREENCHE_bench_top(); // // internal wires // reg wb_clk; reg mc_clk; reg [ 31:0] data; integer data1; reg wb_rst; wire [31:0] wb_dat_i, wb_dat_o; wire [31:0] wb_adr_o; wire wb_cyc_o, wb_stb_o; wire [ 3:0] wb_sel_o; wire wb_ack_i, wb_err_i, wb_rty_i; wire wb_mc_stb; wire [23:0] mc_adr_o; wire [31:0] mc_dq, mc_dq_o; wire [ 3:0] mc_dp, mc_dp_o, pbus_o, pbus_i; reg [ 3:0] set_par; wire [31:0] par_con; reg sel_par, sel_pbus; wire par_sdram_cs; wire mc_doe_o; wire [ 3:0] mc_dqm_o; wire mc_we_o, mc_oe_o; wire mc_ras_o, mc_cas_o, mc_cke_o; wire [ 7:0] mc_cs_o; wire mc_pad_oe; wire mc_adsc_o, mc_adv_o, mc_zz_o; // ssram connections wire ext_br, ext_bg; integer flag = 0; /******************* wires needed to connect master1 to master/slave block*******/ wire [31:0] wbm1_dat_o; wire wbm1_ack_o ; wire wbm1_err_o ; wire wbm1_rty_o ; wire [31:0] wbm1_dat_i ; wire wbm1_we_i ; wire [3:0] wbm1_sel_i ; wire [31:0] wbm1_adr_i ; wire wbm1_cyc_i ; wire wbm1_stb_i ; /******************************************************************************/ /******************* wires needed to connect master2 to master/slave block*******/ wire [31:0] wbm2_dat_o; wire wbm2_ack_o ; wire wbm2_err_o ; wire wbm2_rty_o ; wire [31:0] wbm2_dat_i ; wire wbm2_we_i ; wire [3:0] wbm2_sel_i ; wire [31:0] wbm2_adr_i ; wire wbm2_cyc_i ; wire wbm2_stb_i ; real a ; /******************************************************************************/

Page 207: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 206

Pedro Mota | Pedro Santos

// // hookup modules // // hookup watch-dog counter /*watch_dog #(1024) wdog ( .clk(wb_clk), .cyc_i(wbm1_cyc_i), .ack_i(wbm1_ack_o), .adr_i(wbm1_adr_i) ); watch_dog #(1024) wdog2 ( .clk(wb_clk), .cyc_i(wbm2_cyc_i), .ack_i(wbm2_ack_o), .adr_i(wbm2_adr_i) );*/ // hookup external bus-master model /*bm_model ext_bm( .br(ext_br), .bg(ext_bg), .chk(mc_pad_oe) );*/ // hookup ERR checker err_check err_chk(wb_err_o, sel_par); // hookup CSn checker cs_check cs_chec(mc_cs_o); intercon master_slave( /* -- wishbone master port(s) -- wbm1*/ .wbm1_dat_i(wbm1_dat_o) , .wbm1_ack_i(wbm1_ack_o) , .wbm1_err_i(wbm1_err_o) , //.wbm1_rty_i() , .wbm1_dat_o(wbm1_dat_i) , .wbm1_we_o(wbm1_we_i) , .wbm1_sel_o(wbm1_sel_i) , .wbm1_adr_o(wbm1_adr_i), .wbm1_cyc_o(wbm1_cyc_i), .wbm1_stb_o(wbm1_stb_i), /* -- wbm2 */ .wbm2_dat_i(wbm2_dat_o) , .wbm2_ack_i(wbm2_ack_o) , .wbm2_err_i(wbm2_err_o) , //.wbm2_rty_i() , .wbm2_dat_o(wbm2_dat_i) , .wbm2_we_o(wbm2_we_i) , .wbm2_sel_o(wbm2_sel_i) , .wbm2_adr_o(wbm2_adr_i), .wbm2_cyc_o(wbm2_cyc_i), .wbm2_stb_o(wbm2_stb_i), /* wishbone slave port(s)

Page 208: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 207

Pedro Mota | Pedro Santos

wbs1 */ .wbs1_dat_o(wb_dat_i), .wbs1_ack_o(wb_ack_i) , .wbs1_err_o(wb_err_i) , .wbs1_rty_o(1'b0) , .wbs1_dat_i(wb_dat_o), .wbs1_we_i (wb_we_o), .wbs1_sel_i(wb_sel_o), .wbs1_adr_i(wb_adr_o), .wbs1_cyc_i(wb_cyc_o), .wbs1_stb_i(wb_stb_o), .clk (wb_clk) , .reset (wb_rst ) ); // hookup memory controller mc_top dut ( // wishbone interface .clk_i(wb_clk), .rst_i(wb_rst), .wb_data_i(wb_dat_o), .wb_data_o(wb_dat_i), .wb_addr_i(wb_adr_o), .wb_sel_i(wb_sel_o), .wb_we_i(wb_we_o), .wb_cyc_i(wb_cyc_o), .wb_stb_i(wb_stb_o), .wb_ack_o(wb_ack_i), .wb_err_o(wb_err_i), // memory controller .susp_req_i(1'b0), .resume_req_i(1'b0), .suspended_o(), .poc_o(), .mc_clk_i(mc_clk), .mc_br_pad_i(ext_br), .mc_bg_pad_o(ext_bg), .mc_ack_pad_i(1'b0), .mc_addr_pad_o(mc_adr_o), .mc_data_pad_i(mc_dq), .mc_data_pad_o(mc_dq_o), .mc_dp_pad_i(pbus_i), // attach parity bus .mc_dp_pad_o(mc_dp_o), .mc_doe_pad_doe_o(mc_doe_o), .mc_dqm_pad_o(mc_dqm_o), .mc_oe_pad_o_(mc_oe_o), .mc_we_pad_o_(mc_we_o), .mc_cas_pad_o_(mc_cas_o), .mc_ras_pad_o_(mc_ras_o), .mc_cke_pad_o_(mc_cke_o), .mc_cs_pad_o_(mc_cs_o), .mc_sts_pad_i(1'b0), .mc_rp_pad_o_(), .mc_vpen_pad_o(), .mc_adsc_pad_o_(mc_adsc_o), .mc_adv_pad_o_(mc_adv_o), .mc_zz_pad_o(mc_zz_o), .mc_coe_pad_coe_o(mc_pad_oe) ); // assign memory controller stb_signal assign wb_mc_stb = wb_adr_o[31]; // generate output buffers for memory controller assign mc_dq = mc_doe_o ? mc_dq_o : 32'bz; assign mc_dp = mc_doe_o ? mc_dp_o : 4'bz; // hookup ssrams (CHIP SELECT 4) CY7C1340G_PLDCD cypress

Page 209: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 208

Pedro Mota | Pedro Santos

(.ZZ(mc_zz_o), .Mode(1'b0), .ADDR(mc_adr_o[16:0]), .GW_N(1'b1), .BWE_N(mc_we_o), .BWd_N(mc_dqm_o[3]), .BWc_N(mc_dqm_o[2]), .BWb_N(mc_dqm_o[1]), .BWa_N(mc_dqm_o[0]), .CE1_N(mc_cs_o[4]), .CE2(1'b1), .CE3_N(1'b0), .ADSP_N(1'b1), .ADSC_N(mc_adsc_o), .ADV_N(mc_adv_o), .OE_N(mc_oe_o), .DQ (mc_dq), .CLK (mc_clk) ); /*mt58l1my18d ssram0 ( .Dq( {par_con[24], par_con[16], mc_dq[31:16]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[3]), .Bwb_n(mc_dqm_o[2]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), // ?? .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) ); mt58l1my18d ssram1 ( .Dq( {par_con[8], par_con[0], mc_dq[15:0]} ), .Addr(mc_adr_o[19:0]), .Mode(1'b0), // This input (sometimes called LBO) selects burst order // 1'b0 = linear burst, 1'b1 = interleaved burst .Adv_n(mc_adv_o), .Clk(mc_clk), .Adsc_n(mc_adsc_o), .Adsp_n(1'b1), .Bwa_n(mc_dqm_o[1]), .Bwb_n(mc_dqm_o[0]), // or the otherway around .Bwe_n(mc_we_o), .Gw_n(1'b1), .Ce_n(mc_cs_o[4]), .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(mc_oe_o), .Zz(mc_zz_o) );*/ // hookup sdrams (CHIP SELECT 3) mt48lc16m16a2 sdram0_3( .Dq(mc_dq[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) );

Page 210: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 209

Pedro Mota | Pedro Santos

mt48lc16m16a2 sdram1_3( .Dq(mc_dq[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(mc_cs_o[3]), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup sdrams (CHIP SELECT 2 or PARITY) assign pbus_o = sel_pbus ? (sel_par ? mc_dp : set_par) : mc_dq; assign par_con = {7'bz, pbus_o[3], 7'bz, pbus_o[2], 7'bz, pbus_o[1], 7'bz, pbus_o[0]}; assign pbus_i = {par_con[24], par_con[16], par_con[8], par_con[0]}; assign par_sdram_cs = sel_pbus ? mc_cs_o[3] : mc_cs_o[2]; mt48lc16m16a2 sdram0_2( .Dq(par_con[31:16]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[3:2]) ); mt48lc16m16a2 sdram1_2( .Dq(par_con[15:0]), .Addr(mc_adr_o[12:0]), .Ba(mc_adr_o[14:13]), .Clk(mc_clk), .Cke(mc_cke_o), .Cs_n(par_sdram_cs), .Ras_n(mc_ras_o), .Cas_n(mc_cas_o), .We_n(mc_we_o), .Dqm(mc_dqm_o[1:0]) ); // hookup asynchronous srams (CHIP SELECT 1) A8Kx8 asram0 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[31:24]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram1 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[23:16]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram2 ( .Address(mc_adr_o[12:0]), .dataIO(mc_dq[15: 8]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); A8Kx8 asram3 (

Page 211: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 210

Pedro Mota | Pedro Santos

.Address(mc_adr_o[12:0]), .dataIO(mc_dq[ 7: 0]), .OEn(mc_oe_o), .CE1n(mc_cs_o[1]), .CE2(1'b1), .WEn(mc_we_o) ); /* .wbm1_dat_i(wbm1_dat_o) , .wbm1_ack_i(wbm1_ack_o) , .wbm1_err_i(wbm1_err_o) , .wbm1_rty_i(wbm1_rty_o) , .wbm1_dat_o(1'b0) , .wbm1_we_o(wbm1_we_i) , .wbm1_sel_o(wbm1_sel_i) , .wbm1_adr_o(wbm1_adr_i), .wbm1_cyc_o(wbm1_cyc_i), .wbm1_stb_o(wbm1_stb_i), */ // hookup wishbone master wb_master_model wbm( .clk(wb_clk), .rst(wb_rst), .adr(wbm1_adr_i), .din(wbm1_dat_o), .dout(wbm1_dat_i), .cyc(wbm1_cyc_i), .stb(wbm1_stb_i), .we(wbm1_we_i), .sel(wbm1_sel_i), .ack(wbm1_ack_o), .err(wbm1_err_o), .rty(1'b0) ); /* wire [31:0] wbm1_dat_o wire wbm1_ack_o ; wire wbm1_err_o ; wire wbm1_rty_o ; wire [31:0] wbm1_dat_i ; wire wbm1_we_i ; wire [3:0] wbm1_sel_i ; wire [31:0] wbm1_adr_i ; wire wbm1_cyc_i ; wire wbm1_stb_i ; */ /* --------------------------------------- master 2 -----------------------*/ wb_master_model wbm2( .clk(wb_clk), .rst(wb_rst), .adr(wbm2_adr_i), .din(wbm2_dat_o), .dout(wbm2_dat_i), .cyc(wbm2_cyc_i), .stb(wbm2_stb_i), .we(wbm2_we_i), .sel(wbm2_sel_i), .ack(wbm2_ack_o), .err(wbm2_err_o), .rty(1'b0) ); // // testbench body //

Page 212: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 211

Pedro Mota | Pedro Santos

assign wb_rty_i = 1'b0; // no retries from memory controller // generate clock always #20 wb_clk <= ~wb_clk; always@(posedge wb_clk) // mc_clk <= #1 ~mc_clk; mc_clk <= #0 ~mc_clk; // initial statements // testbench original!!!!! /*initial begin a=0; # 100000; $display (" operando com o master 2\n"); //teste_m2; while (a<2000) begin $display (" Escrita do master 2 \n"); wbm2.wb_write(0, 0, 32'h1000_0000, 32'hff_dd_ee_cc); // program base address register $display (" leitura e comparação do master 2\n"); wbm2.wb_read(0, 0, 32'h1000_0fff, data); /* $display (" Escrita do master 2 \n"); wbm2.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR // check written data $display (" leitura e comparação do master 2\n"); wbm2.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); a=a+1; //if (a==1) flag=1; $display (" o valor do data é %h\n",data); end end */ initial begin wb_clk = 0; // start with low-level clock wb_rst = 1; // assert reset mc_clk = 0; sel_par = 1; // do not modify parity bits sel_pbus = 1; // use second SDRAMS set as parity sdrams repeat(20) @(posedge wb_clk); wb_rst = 0; // negate reset @(posedge wb_clk); run_tests; #30000; // show total errors detected wbm.show_tot_err_cnt; wbm2.show_tot_err_cnt; $stop; end //////////////////////

Page 213: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 212

Pedro Mota | Pedro Santos

// // Internal tasks // task run_tests; begin prg_mc; // program memory controller BA-mask and CSR registers // force sdram0_3.Debug = 1'b1; // turn on SDRAM debug option force sdram0_3.Debug = 1'b0; // turn off SDRAM debug option /////////////// // SDRAM tests // tst_sdram_memfill; // test sdrams: Fill entire memory and verify // tst_sdram_parity; // test sdrams: Parity generation // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_sdram_rnd; // test sdrams: Fill-Verify, random access // tst_sdram_rmw_seq; // test sdrams: Read-Modify-Write test, sequential access // tst_sdram_rmw_rnd; // test sdrams: Read-Modify-Write test, random access // tst_sdram_blk_cpy1; // test sdrams: Perform block copy, different src and dest. address // tst_sdram_blk_cpy2; // test sdrams: Perform block copy, src and dest same address // tst_sdram_bytes; // test sdrams: Peform byte accesses ////////////////////////////// // ASYNCHRONOUS MEMORIES TEST // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back //////////////// // SSRAMS TESTS //teste_m1; // tst_ssram_seq; fill; ////////////////////// // MULTI MEMORY TESTS // tst_blk_cpy1; // test block-copy: access sdrams + asrams // The next test (tst_blk_cyp2) is, saddly to say, useless. // It tests n-by-n situations for multiple SDRAMS, testing all possible settings for each SDRAM. // It is supposed to test the independence for each SDRAM chip-select. // However it is to time-consuming; it runs for about a month on an Athlon-XP 1800 system // tst_blk_cpy2; // test block-copy: access multiple sdrams ///////////////////////////// // EXTERNAL BUS MASTER TESTS // turn on external bus-master and rerun some tests // force ext_bm.on_off = 1'b1; // tst_sdram_seq; // test sdrams: Fill-Verify, sequential access // tst_amem_seq; // test asynchronous memory // tst_amem_b2b; // test asynchronous memory back-2-back // tst_blk_cpy1; // test block-copy: access sdrams + asrams end endtask // run_tests task prg_mc; begin wbm.wb_write(0, 0, 32'h6000_0008, `BA_MASK); // program base address register wbm.wb_write(0, 0, 32'h6000_0000, 32'h6000_0400); // program CSR

Page 214: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 213

Pedro Mota | Pedro Santos

// check written data $display(" teste da configuração\n"); wbm.wb_cmp(0, 0, 32'h6000_0008, `BA_MASK); wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h6000_0400); end endtask //prg_mc //////////////////////////////// // Register test // task reg_test; begin end endtask // reg_test ///////////////////////// // include memory tests // // `include "tst_sdram.v" // `include "tst_asram.v" `include "tst_ssram_1.v" `include "tst_ssram_2.v" `include "tst_ssram.v" // `include "tst_multi_mem.v" `include "func.v" Endmodule

Page 215: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 214

Pedro Mota | Pedro Santos

Anexo 15: Or1k TOP level

Page 216: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 215

Pedro Mota | Pedro Santos

Anexo 16: mc_defines.v ///////////////////////////////////////////////////////////////////// //// //// //// WISHBONE Memory Controller Definitions //// //// //// //// //// //// Author: Rudolf Usselmann //// //// [email protected] //// //// //// //// //// //// Downloaded from: http://www.opencores.org/cores/mem_ctrl/ //// //// //// ///////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000-2002 Rudolf Usselmann //// //// www.asics.ws //// //// [email protected] //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer.//// //// //// //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// //// POSSIBILITY OF SUCH DAMAGE. //// //// //// ///////////////////////////////////////////////////////////////////// // CVS Log // // $Id: mc_defines.v,v 1.1 2002/03/06 15:10:34 rherveille Exp $ // // $Date: 2002/03/06 15:10:34 $ // $Revision: 1.1 $ // $Author: rherveille $ // $Locker: $ // $State: Exp $ // // Change History: // $Log: mc_defines.v,v $ // Revision 1.1 2002/03/06 15:10:34 rherveille // Initial release // // Revision 1.6 2001/12/12 06:35:15 rudi // *** empty log message *** // // Revision 1.5 2001/12/11 02:47:19 rudi // // - Made some changes not to expect clock during reset ... // // Revision 1.4 2001/11/29 02:16:28 rudi // // // - More Synthesis cleanup, mostly for speed // - Several bug fixes // - Changed code to avoid auto-precharge and // burst-terminate combinations (apparently illegal ?) // Now we will do a manual precharge ... // // Revision 1.3 2001/09/10 13:44:17 rudi // *** empty log message *** // // Revision 1.2 2001/08/10 08:16:21 rudi //

Page 217: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 216

Pedro Mota | Pedro Santos

// - Changed IO names to be more clear. // - Uniquifyed define names to be core specific. // - Removed "Refresh Early" configuration // // Revision 1.1 2001/07/29 07:34:41 rudi // // // 1) Changed Directory Structure // 2) Fixed several minor bugs // // Revision 1.3 2001/06/12 15:19:49 rudi // // // Minor changes after running lint, and a small bug // fix reading csr and ba_mask registers. // // Revision 1.2 2001/06/03 11:37:17 rudi // // // 1) Fixed Chip Select Mask Register // - Power On Value is now all ones // - Comparison Logic is now correct // // 2) All resets are now asynchronous // // 3) Converted Power On Delay to an configurable item // // 4) Added reset to Chip Select Output Registers // // 5) Forcing all outputs to Hi-Z state during reset // // Revision 1.1.1.1 2001/05/13 09:39:38 rudi // Created Directory Structure // // // // `timescale 1ns / 10ps ///////////////////////////////////////////////////////////////////// // // This define selects how the WISHBONE interface determines if // the internal register file is selected. // This should be a simple address decoder. "wb_addr_i" is the // WISHBONE address bus (32 bits wide). `define MC_REG_SEL (wb_addr_i[31:29] == 3'b011) // This define selects how the WISHBONE interface determines if // the memory is selected. // This should be a simple address decoder. "wb_addr_i" is the // WISHBONE address bus (32 bits wide). `define MC_MEM_SEL (wb_addr_i[31:29] == 3'h0) ///////////////////////////////////////////////////////////////////// // // This are the default Power-On Reset values for Chip Select // // This will be defined by the run script for my test bench ... // Alternatively force here for synthesis ... `define RUDIS_TB 1 // Defines which chip select is used for Power On booting // To run my default testbench default boot CS must be 3 !!! `ifdef RUDIS_TB `define MC_DEF_SEL 3'h3 `else `define MC_DEF_SEL 3'h0 `endif // Defines the default (reset) TMS value for the DEF_SEL chip select `define MC_DEF_POR_TMS 32'hffff_ffff /////////////////////////////////////////////////////////////////////

Page 218: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 217

Pedro Mota | Pedro Santos

// // Define how many Chip Selects to Implement // `define MC_HAVE_CS1 1 //`define MC_HAVE_CS2 1 //`define MC_HAVE_CS3 1 //`define MC_HAVE_CS4 1 //`define MC_HAVE_CS5 1 //`define MC_HAVE_CS6 1 //`define MC_HAVE_CS7 1 // To run my default testbench those need to there !!! `ifdef RUDIS_TB `define MC_HAVE_CS2 1 `define MC_HAVE_CS3 1 `define MC_HAVE_CS4 1 `define MC_HAVE_CS5 1 `endif ///////////////////////////////////////////////////////////////////// // // Init Refresh // // Number of Refresh Cycles to perform during SDRAM initialization. // This varies between SDRAM manufacturer. Typically this value is // between 2 and 8. This number must be smaller than 16. `define MC_INIT_RFRC_CNT 2 ///////////////////////////////////////////////////////////////////// // // Power On Delay // // Most if SDRAMs require some time to initialize before they can be used // after power on. If the Memory Controller shall stall after power on to // allow SDRAMs to finish the initialization process uncomment the below // define statement `define MC_POR_DELAY 1 // This value defines how many MEM_CLK cycles the Memory Controller should // stall. Default is 2.5uS. At a 10nS MEM_CLK cycle time, this would 250 // cycles. `define MC_POR_DELAY_VAL 8'd250 // =============================================================== // =============================================================== // Various internal defines (DO NOT MODIFY !) // =============================================================== // =============================================================== // Register settings encodings `define MC_BW_8 2'h0 `define MC_BW_16 2'h1 `define MC_BW_32 2'h2 `define MC_MEM_TYPE_SDRAM 3'h0 `define MC_MEM_TYPE_SRAM 3'h1 `define MC_MEM_TYPE_ACS 3'h2 `define MC_MEM_TYPE_SCS 3'h3 `define MC_MEM_SIZE_64 2'h0 `define MC_MEM_SIZE_128 2'h1 `define MC_MEM_SIZE_256 2'h2 // Command Valid, Ras_, Cas_, We_ `define MC_CMD_NOP 4'b0111 `define MC_CMD_PC 4'b1010 `define MC_CMD_ACT 4'b1011 `define MC_CMD_WR 4'b1100 `define MC_CMD_RD 4'b1101 `define MC_CMD_BT 4'b1110 `define MC_CMD_ARFR 4'b1001 `define MC_CMD_LMR 4'b1000 `define MC_CMD_XRD 4'b1111 `define MC_CMD_XWR 4'b1110 `define MC_SINGLE_BANK 1'b0

Page 219: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 218

Pedro Mota | Pedro Santos

`define MC_ALL_BANKS 1'b1

Page 220: Hardware/Software co-design para aplicações de ...ee00022/Relatorio_projecto_ee00022_ee00115.… · Hardware/Software co-design para aplicações de processamento de voz - Pedro

Hardware/Software co-design para aplicações de processamento de voz 219

Pedro Mota | Pedro Santos

Anexo 17 : Top level do master slave