um estudo sobre a construção, desempenho e …

131
UNIVERSIDADE ESTADUAL DE CAMPINAS FACULDADE DE ENGENHARIA ELÉTRICA E DE COMPUTAÇÃO ANTÔNIO UNIAS DE LUCENA Um estudo sobre a construção, desempenho e implementação em VHDL de códigos LDPC binários, irregulares e estruturados para aplicação em comunicações ópticas CAMPINAS 2015

Upload: others

Post on 22-Oct-2021

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Um estudo sobre a construção, desempenho e …

UNIVERSIDADE ESTADUAL DE CAMPINAS

FACULDADE DE ENGENHARIA ELÉTRICA E DE COMPUTAÇÃO

ANTÔNIO UNIAS DE LUCENA

Um estudo sobre a construção, desempenho e implementação em VHDL de códigos

LDPC binários, irregulares e estruturados para aplicação em comunicações ópticas

CAMPINAS

2015

Page 2: Um estudo sobre a construção, desempenho e …

ANTÔNIO UNIAS DE LUCENA

Um estudo sobre a construção, desempenho e implementação em VHDL de códigos

LDPC binários, irregulares e estruturados para aplicação em comunicações ópticas

CAMPINAS

2015

Dissertação apresentada à Faculdade de Engenharia Elétrica e Computação da Universidade Estadual de Campinas como parte dos requisitos exigidos para a obtenção do título de mestre em Engenharia Elétrica. Área de concentração: Telecomunicações e Telemática.

Este exemplar corresponde à vesão final da dissertação defendida pelo aluno Antônio Unias de Lucena e orientada pelo Prof. Dr. Renato Baldini Filho. Assinatura do Orientador:

Page 3: Um estudo sobre a construção, desempenho e …

Agência(s) de fomento e nº(s) de processo(s): Não se aplica.

Ficha catalográficaUniversidade Estadual de Campinas

Biblioteca da Área de Engenharia e ArquiteturaLuciana Pietrosanto Milla - CRB 8/8129

Lucena, Antônio Unias de, 1981- L963e LucUm estudo sobre a construção, desempenho e implementação em VHDL

de códigos LDPC binários, irregulares e estruturados para aplicação emcomunicações ópticas / Antônio Unias de Lucena. – Campinas, SP : [s.n.],2015.

LucOrientador: Renato Baldini Filho. LucDissertação (mestrado) – Universidade Estadual de Campinas, Faculdade

de Engenharia Elétrica e de Computação.

Luc1. Comunicações ópticas. 2. Códigos corretores de erro (Teoria da

informação). 3. VHDL (Linguagem descritiva de hardware). 4. FPGA. I. Filho,Renato Baldini,1956-. II. Universidade Estadual de Campinas. Faculdade deEngenharia Elétrica e de Computação. III. Título.

Informações para Biblioteca Digital

Título em outro idioma: A study of construction, performance and VHDL implementation ofirregular, structured and binary LDPC codes for optical communications.Palavras-chave em inglês:Optical communicationsError-correcting codes (Information theory)VHDL (Hardware descriptive language)FPGAÁrea de concentração: Telecomunicações e TelemáticaTitulação: Mestre em Engenharia ElétricaBanca examinadora:Renato Baldini Filho [Orientador]Lucas Heitzmann GabrielliFabbryccio Akkazzha Chaves Machado CardosoData de defesa: 15-10-2015Programa de Pós-Graduação: Engenharia Elétrica

Powered by TCPDF (www.tcpdf.org)

Page 4: Um estudo sobre a construção, desempenho e …

COMISSÃO JULGADORA - DISSERTAÇÃO DE MESTRADO

Candidato: Antônio Unias de Lucena RA: 075031

Data da Defesa: 15 de outubro de 2015

Título da Tese: "Um Estudo Sobre a Construção, Desempenho e Implementação em

VHDL de Códigos LDPC Binários, Irregulares e Estruturados para Aplicação em

Comunicações Ópticas”.

Prof. Dr. Renato Baldini Filho (Presidente, FEEC/Unicamp)

Dr. Fabbryccio Akkazzha Chaves Machado Cardoso (CPqD)

Prof. Dr. Lucas Heitzmann Gabrielli (FEEC/UNICAMP)

A ata de defesa, com as respectivas assinaturas dos membros da Comissão

Julgadora, encontra-se no processo de vida acadêmica do aluno.

Page 5: Um estudo sobre a construção, desempenho e …

DEDICATÓRIA

Aos meus pais

Page 6: Um estudo sobre a construção, desempenho e …

AGRADECIMENTOS

Agradeço à minha família, ao meu orientador, Renato Baldini Filho, pela paciência e apoio

durante o mestrado, e aos meus amigos pelas ideias e auxílio nas correções desta dissertação.

Page 7: Um estudo sobre a construção, desempenho e …

RESUMO

O emprego de códigos LDPC em comunicações ópticas vem recebendo especial atenção nos últimos

anos devido à sua elevada capacidade de correção de erros, fato que possibilita enlaces mais longos e

com maior capacidade de transmissão. A presente dissertação apresenta um estudo de códigos LDPC

binários, irregulares e estruturados (IE-LDPC), bem como, uma comparação do desempenho de dois

algoritmos de decodificação comumente utilizados na decodificação de códigos LDPC: o algoritmo

soma-produto utilizando razões logarítmicas (log-SP) e o algoritmo soma-mínimo (SM), para um

conjunto de códigos IE-LDPC construídos. Além disso, a presente dissertação apresenta uma

implementação em VHDL de um codificador e de um decodificador para códigos IE-LDPC e os

resultados da síntese em FPGA desta implementação em VHDL. A comparação do desempenho dos

algoritmos de decodificação foi importante para determinar que o algoritmo SM, uma simplificação do

algoritmo log-SP, pode ser utilizado no lugar deste último sem perdas significativas de desempenho.

Por sua vez, a síntese em FPGA do codificador e do decodificador dos códigos IE-LDPC construídos

mostrou-se factível, mas a arquitetura do decodificador implementado do algoritmo SM ainda utiliza

grande quantidade de elementos lógicos.

Palavras-chave: comunicações ópticas, códigos corretores de erro, VHDL (linguagem descritiva de

hardware), FPGA.

Page 8: Um estudo sobre a construção, desempenho e …

ABSTRACT

The use of LDPC codes on optical communications has received special attention in recent years due to

its error correction capability, permitting longer and higher capacity optical links. This dissertation

presents a study of binary irregular structured LDPC codes (IS-LDPC), as well as a performance

comparison between two LDPC decoding algorithms: logarithm domain sum-product (log-SP) and

minimum-sum (MS) for a set of constructed IS-LDPC codes. Besides, this dissertation presents a

VHDL implementation of an encoder and a decoder for IS-LDPC codes and the FPGA synthesis results

of this VHDL implementation. The performance comparison has determined that the MS algorithm can

be a substitute to the log-SP algorithm with a significant reduction in logical elements in FPGA

implementation, without significant loss in decoding performance. The FPGA synthesis results have

shown that the encoder and the decoder IS-LDPC implementations are feasible, but the current MS

decoder still uses a considerable amount of logical elements.

Keywords: optical communications, error-correcting codes, VHDL, FPGA.

Page 9: Um estudo sobre a construção, desempenho e …

LISTA DE FIGURAS

Figura 1.1 – Comparativo entre o desempenho de vários códigos corretores de erros utilizados em

comunicações ópticas [2]. ............................................................................................................... 20

Figura 2.1 – Exemplo de um gráfico de Tanner para um código LDPC (8, 4). ..................................... 23

Figura 2.2 – Exemplo de uma matriz H com girth igual a 4 e seu respectivo gráfico de Tanner. ......... 24

Figura 2.3 – Matrizes circulantes obtidas a partir da rotação de I 8. ....................................................... 25

Figura 2.4 – Matriz de verificação de paridade de um código IE-LDPC (32, 16). ................................ 26

Figura 2.5 – Matriz de verificação de paridade de um código IE-LDPC (24, 16). ................................ 26

Figura 2.6 – Passo Horizontal da decodificação LDPC. ........................................................................ 30

Figura 2.7 – Passo Vertical da decodificação LDPC. ............................................................................ 30

Figura 2.8 – Fluxograma da decodificação LDPC. ................................................................................ 32

Figura 2.9 – Conjunto de trilhas e portas lógicas de FPGA antiga. ....................................................... 36

Figura 2.10 – FPGA e seus componentes internos [10]. ........................................................................ 37

Figura 2.11 – Célula básica da Virtex-5 [10]. ......................................................................................... 38

Figura 2.12 – Diagrama de um sistema de comunicações ópticas. ........................................................ 39

Figura 2.13 – Notação em ponto fixo empregada na presente dissertação. ........................................... 42

Figura 2.14 – Interface óptica-elétrica. .................................................................................................. 42

Figura 2.15 – Visão global do contexto em que o codificador e decodificador LDPC é empregado. ... 43

Figura 3.1 – Componentes da Virtex-5 interligados por trilhas internas [10]. ....................................... 45

Figura 3.2 – Atraso dentro da Virtex-5 devido ao caminho combinacional. .......................................... 46

Figura 3.3 – Codificador LDPC. ............................................................................................................ 47

Figura 3.4 – Blocos do decodificador LDPC. ........................................................................................ 48

Figura 3.5 – Matrizes auxiliares obtidas a partir da matriz H. .............................................................. 49

Figura 3.6 – Passo Horizontal do decodificador LDPC. ........................................................................ 51

Figura 3.7 – Passo Vertical do decodificador LDPC. ............................................................................ 52

Figura 3.8 – Calculador de �(��). ......................................................................................................... 54

Figura 3.9 – Calculador de síndrome do decodificador LDPC. ............................................................. 55

Figura 3.10 – Propagação dos dados ao longo dos vários blocos do decodificador.. ............................ 57

Figura 4.1 – Cenário da simulação dos códigos IE-LDPC. ................................................................... 59

Figura 4.2 – Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz

Page 10: Um estudo sobre a construção, desempenho e …

identidade de ordem igual a 50. ...................................................................................................... 60

Figura 4.3 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 100. .................................................................................................... 61

Figura 4.4 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 200. .................................................................................................... 62

Figura 4.5 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 500. .................................................................................................... 63

Figura 4.6 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma

matriz identidade de ordem igual a 50. ........................................................................................... 64

Figura 4.7 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma

matriz identidade de ordem igual a 100. ......................................................................................... 65

Figura 4.8 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma

matriz identidade de ordem igual a 200. ......................................................................................... 66

Figura 4.9 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma

matriz identidade de ordem igual a 500. ......................................................................................... 67

Figura 4.10 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma

matriz identidade de ordem igual a 1000. ....................................................................................... 68

Page 11: Um estudo sobre a construção, desempenho e …

LISTA DE TABELAS

Tabela 4.1- Parâmetros do codificador e do decodificador do código IE-LDPC (40, 20) na FGPA ..... 69

Tabela 4.2 - Parâmetros do codificador e do decodificador do código IE-LDPC (200, 100) na FGPA 69

Page 12: Um estudo sobre a construção, desempenho e …

LISTA DE SIGLAS E ABREVIATURAS

ASIC - Application Specific Integrated Circuit

AWGN - Additive White Gaussian Noise

BCH - Bose-Chaudhuri-Hocquenghem

BER - Bit Error Rate

BI-AWGN - Binary Input Additive White Gaussian Noise

CLB - Configurable Logic Blocks

DLL - Delay-locked Loop

FPGA - Field Programmable Gate Array

Gbps - Gigabit por segundo

IE-LDPC - Códigos LDPC irregulares e estruturados

IS-LDPC - Irregular and structured LDPCcodes

ITU-T - International Telecommunication Union

LDPC - Low-Density Parity-Check

log-SP - Soma-Produto utilizando razões logarítmicas

LUT - Look-up table

MS - Minimum-Sum

OFDM - Orthogonal Frequency-Division Multiplexing

PLL - Phase-Locked Loop

PSK - Phase Shift Keying

QAM - Quadrature Amplitude Modulation

QC-LDPC - Códigos LDPC quase-cíclicos

RAM - Random Access Memory

RS - Reed-Solomon

SP - Soma-Produto

SM - Soma-Mínimo

VHDL - VHSIC Hardware Description Language

WDM - Wavelength Division Multiplexing

WIMAX - Worldwide Interoperability for Microwave Access

Wi-Fi - Wireless Fidelity

Page 13: Um estudo sobre a construção, desempenho e …

LISTA DE SÍMBOLOS

�� - j-ésimo nó de verificação

c(i) - Bit i da palavra transmitida pelo codificador LDPC �̂(�) - Bit i da palavra decodificada pelo código LDPC

c - Palavra codificada pelo código LDPC ̂ - Palavra decodificada pelo código LDPC

Cl,j - Matriz circulante de ordem l e com j colunas rotacionadas à direita

C - Submatriz formada por todas as matrizes circulantes que formam a matriz H � - Conjunto dos nós de verificação conectados ao nó de variável �� �\� - Conjunto de nós de verificação conectados ao nó de variável �� excetuando o

nó de verificação �� �� - Energia por bit

Eb/N0 - Razão entre a energia por bit e a densidade espectral de potência do ruído

�(�, �) - Elemento da linha j e coluna i da matriz G

G - Matriz geradora do código LDPC ℎ(�, �) - Elemento da linha j e coluna i da matriz H

H - Matriz de verificação de paridade do código LDPC �� - Matriz H após a transformação utilizando-se o algoritmo de Gauss-Jordan �� - Matriz H transposta ���� - Matriz formada com os números das colunas e das linhas da matriz H em que ℎ(�, �) = 1 ���� - Matriz formada com os números das linhas e das colunas da matriz H em que ℎ(�, �) = 1 �� - Matriz identidade de ordem k �(� �) - Matriz identidade de ordem (n-k)

k - Número de bits da palavra a ser codificada !� - Fator de normalização para garantir ��(0) + ��(1) = 1 !�� - Fator de normalização para garantir &��(0) + &��(1) = 1 �(��) - Logaritmo da razão de verossimilhança da informação intrínseca recebida pelo

Page 14: Um estudo sobre a construção, desempenho e …

decodificador �(&��) - Logaritmo da razão de verossimilhança da mensagem envidada do nó de

variável �� para o nó de verificação �� �('��) - Logaritmo da razão de verossimilhança da mensagem enviada do nó de

verificação �� para o nó de variável �� �(��) - Logaritmo da razão de verossimilhança da probabilidade a posteriori para cada

nó de variável �� m - Palavra a ser codificada

n - Número de bits da palavra codificada () - Densidade espectral de potência de ruído *+ - Conjunto formado pelos números primos naturais

p - Fator de paralelismo da interface óptico-elétrico

P - Matriz de paridade do código LDPC ,� - Matriz de paridade transposta do código LDPC -� - Pr (�� = 1|1�), probabilidade a posteriori de que o bit c(i) seja 1, dado que o bit 1� foi recebido 2� - Matriz nula de ordem k

q - Quantidade de bits empregados para quantizar o valor do sinal óptico &�� - Mensagem do nó de variável �� para o nó de verificação �� �� - Probabilidade a posteriori para cada nó de variável �� '�� - Mensagem do nó de verificação �� para o nó de variável �� s(j) - Bit j da síndrome da palavra decodificada

s - Síndrome da palavra decodificada

t - instante de tempo t �� - i-ésimo nó de variável 3� - Conjunto dos nós de variável conectados ao nó de verificação �� 3�\� - Conjunto de nós de variável conectados ao nó de verificação �� excetuando o nó

de variável �� 45 - Quantidade de 1s por coluna da matriz H 46 - Quantidade de 1s por linha da matriz H

Page 15: Um estudo sobre a construção, desempenho e …

1� - Bit i da palavra recebida pelo decodificador

y - Palavra recebida pelo decodificador LDPC

7�� - sinal de �(&��) 8�� - magnitude de �9&��: ;< - variância do ruído do canal de transmissão

Page 16: Um estudo sobre a construção, desempenho e …

SUMÁRIO

1 INTRODUÇÃO .................................................................................................................. 19

2 FUNDAMENTAÇÃO TEÓRICA ...................................................................................... 22

2.1 Códigos LDPC ............................................................................................................ 22

2.1.1 Representação gráfica de códigos LDPC ................................................................ 22

2.1.2 Construção de códigos LDPC ................................................................................. 23

2.1.2.1 Códigos LDPC binários, irregulares e estruturados ......................................... 24

2.1.3 Codificação ............................................................................................................. 27

2.1.4 Decodificação .......................................................................................................... 28

2.1.4.1 Algoritmo soma-produto (SP) .......................................................................... 28

2.1.4.2 Algoritmo soma-produto utilizando razões logarítmicas (log-SP) ................... 32

2.1.4.3 Algoritmo soma-mínimo (SM) ......................................................................... 35

2.2 FPGA - Field-Programmable Gate Array.................................................................... 35

2.3 Códigos corretores de erro para comunicações ópticas .............................................. 38

2.3.1 Interface óptica-elétrica para utilizar códigos LDPC em comunicações ópticas .... 41

3 IMPLEMENTAÇÃO .......................................................................................................... 44

3.1 Influências dos componentes da Virtex-5 na implementação do codificador e do

decodificador IE-LDPC ...................................................................................................................... 44

3.1.1 Trilhas internas e frequência máxima de operação ................................................. 45

3.1.2 Memórias internas ................................................................................................... 46

3.2 Implementação do código IE-LDPC ........................................................................... 46

3.2.1 Codificador.............................................................................................................. 46

3.2.2 Decodificador .......................................................................................................... 47

3.2.2.1 Calculador do Passo Horizontal ........................................................................ 50

3.2.2.2 Calculador do Passo Vertical ............................................................................ 52

3.2.2.3 Decisão ............................................................................................................. 53

3.2.2.4 Propagação dos dados dentro do decodificador ................................................ 55

Page 17: Um estudo sobre a construção, desempenho e …

4 RESULTADOS ................................................................................................................... 58

4.1 Comparação do desempenho dos algoritmos de decodificação log-SP e SM para os

códigos IE-LDPC construídos ............................................................................................................ 58

4.1.1 Resultados da comparação do desempenho dos algoritmos log-SP e SM para os

códigos IE-LDPC (2000, 1000) ...................................................................................................... 59

4.1.1.1 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 50 ................................................................................................... 59

4.1.1.2 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 100 ................................................................................................. 60

4.1.1.3 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 200 ................................................................................................. 61

4.1.1.4 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 500 ................................................................................................. 62

4.1.2 Resultados da comparação do desempenho dos algoritmos log-SP e SM para os

códigos IE-LDPC (4000, 2000) ...................................................................................................... 63

4.1.2.1 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 50 ................................................................................................... 64

4.1.2.2 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 100 ................................................................................................. 64

4.1.2.3 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 200 ................................................................................................. 65

4.1.2.4 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 500 ................................................................................................. 66

4.1.2.5 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 1000 ............................................................................................... 67

4.2 Resultados da síntese em FPGA do codificador e do decodificador LDPC ............... 68

5 CONCLUSÃO E TRABALHOS FUTUROS ..................................................................... 71

5.1 Conclusão .................................................................................................................... 71

5.2 Trabalhos Futuros ........................................................................................................ 71

Page 18: Um estudo sobre a construção, desempenho e …

REFERÊNCIAS BIBLIOGRÁFICAS ........................................................................................ 73

ANEXOS ..................................................................................................................................... 76

ANEXO A – Código-fonte dos arquivos desenvolvidos para realizar a análise do desempenho

dos algoritmos log-SP e SM utilizando os códigos IE-LDPC construídos ............................................. 77

ANEXO B - Código-fonte dos arquivos desenvolvidos para a implementação em VHDL do

codificador e do decodificador dos códigos IE-LDPC construídos ........................................................ 91

ANEXO C – Código-fonte dos arquivos utilizados na validação da simulação dos codificadores

e decodificadores implementados em VHDL. ...................................................................................... 121

Page 19: Um estudo sobre a construção, desempenho e …

19

1 INTRODUÇÃO

O crescimento da Internet mediante o aumento no número de seus usuários, o surgimento de

novos serviços como comunicação em vídeo, televisão de alta definição, computação em nuvem e

vídeos de alta definição, bem como, o crescimento do número de usuários em redes de comunicações

móveis têm criado a necessidade de aumentar a capacidade de transmissão de dados das redes de

comunicações ópticas existentes.

Uma rede de comunicações ópticas é uma de rede de transporte de telecomunicações em que a

transmissão de dados é feita no domínio óptico, utilizando como meio de transmissão as fibras ópticas.

Os maiores desafios atuais enfrentados por estas redes são: aumento das taxas de transmissão, o

número de comprimentos de onda multiplexados numa fibra óptica e a extensão dos enlaces ópticos.

Associados a estes desafios estão o desenvolvimento de novos formatos de modulação, de técnicas de

detecção coerente e de métodos de controle dos efeitos da atenuação, dispersão e não linearidade nas

fibras.

Uma forma de aumentar a capacidade de transmissão de uma rede de comunicações ópticas é

utilizando novos formatos de modulação associados a códigos corretores de erro. Os códigos corretores

de erro são empregados com a função de permitir o aumento do alcance e da capacidade de transmissão

do enlace óptico sem as degradações dos dados transmitidos ocasionadas pelo canal de transmissão

óptica através da fibra. Entre estas degradações destacam-se fatores como dispersão cromática,

dispersão do modo de polarização, interferência entre símbolos e atenuação devido à fibra em que o

dado é transmitido.

Atualmente códigos corretores de erro utilizados em conjunto com a modulação do sinal óptico

possibilitam a transmissão de dados a taxas acima de 100 Gbps com detecção coerente.

Os primeiros códigos corretores de erros utilizados em comunicações ópticas foram os códigos

Reed-Solomon (RS) [1], com destaque para o código RS(255,239), especificado pela norma ITU-T

G.709. Objetivando melhor desempenho, novos códigos foram introduzidos, bem como o uso de

códigos concatenados [1], conforme determina a norma ITU-T G.975.1, sendo estes considerados a

segunda geração de códigos corretores de erros para comunicações ópticas. Os códigos LDPC (Low-

Density Parity-Check) [1], devido ao seu alto desempenho, são considerados a terceira geração de

códigos corretores de erros para comunicações ópticas.

A Figura 1.1 mostra o desempenho de vários códigos em função da redundância (redundancy)

Page 20: Um estudo sobre a construção, desempenho e …

20

adicionada aos dados transmitidos. Net coding gain (ganho de codificação) é a medida da diferença em

dB da relação sinal-ruído para um sistema óptico com código corretor de erro e do mesmo sistema sem

codificação para uma mesma taxa de erro. Redundância é a razão entre a quantidade de bits que é

adicionada à mensagem transmitida pela quantidade total de bits transmitidos.

Figura 1.1 – Comparativo entre o desempenho de vários códigos corretores de erros utilizados em comunicações

ópticas [2].

O ideal para um sistema óptico de comunicações é um código corretor de erro com alto ganho

de codificação e baixa redundância. O código RS(255, 239), por exemplo, possui 5,6 dB de ganho de

codificação e 6,67% de redundância. O código BCH(1020, 988) tem a mesma redundância de 6,67% e

ganho de codificação em torno de 8 dB. A vantagem deste último código sobre o anterior é que ele

proporciona um enlace de alcance maior e robustez a ruídos a um sistema de comunicações ópticas.

Os esforços atuais na área de códigos LDPC para comunicações concentram-se no

desenvolvimento de códigos mais eficazes [1], no desenvolvimento de arquiteturas que utilizem menor

número de elementos lógicos para seus codificadores e decodificadores [1] e no estudo do uso de

códigos LDPC conjuntamente com modulação [1].

Sabendo da importância de códigos LDPC para comunicações ópticas, esta dissertação tem por

objetivo a:

Page 21: Um estudo sobre a construção, desempenho e …

21

a) Construção de códigos LDPC binários, irregulares e estruturados (IE-LDPC);

b) Comparação do desempenho de dois algoritmos de decodificação de códigos LDPC: o algo-

ritmo soma-produto utilizando razões logarítmicas (log-SP) e o algoritmo soma-mínimo

(SM);

c) Implementação em VHDL (VHSIC Hardware Description Language) de um codificador e

de um decodificador baseado no algoritmo SM para códigos IE-LDPC;

d) Síntese em FPGA (Field Programmable Gate Array) do codificador e do decodificador IE-

LDPC descritos em VHDL.

A presente dissertação está organizada da seguinte forma. O capítulo 2 fornece a fundamentação

teórica da construção de códigos LDPC, uma introdução sobre FPGAs e comunicações ópticas. O

capítulo 3 descreve os detalhes da implementação em VHDL da arquitetura do codificador e do

decodificador dos códigos IE-LDPC construídos. O capítulo 4, por sua vez, apresenta os resultados da

comparação do desempenho dos algoritmos de decodificação log-SP e SM para os códigos IE-LDPC e,

também, os resultados da síntese em FPGA de codificadores e decodificadores IE-LDPC. Por fim, o

capítulo 5 é a conclusão e a descrição dos trabalhos futuros.

Existe ainda um apêndice com o código-fonte dos arquivos desenvolvidos para realizar a análise

do desempenho dos algoritmos log-SP e SM utilizando os códigos IE-LDPC construídos, um apêndice

com o código-fonte dos arquivos desenvolvidos para realizar a implementação em VHDL do

codificador e do decodificador IE-LDPC e outro apêndice com o código-fonte dos arquivos utilizados

na validação da simulação dos codificadores e decodificadores implementados em VHDL.

Page 22: Um estudo sobre a construção, desempenho e …

22

2 FUNDAMENTAÇÃO TEÓRICA

Este capítulo tem por objetivo fornecer uma fundamentação teórica sobre códigos LDPC (Low-

Density Parity-Check) e também noções básicas sobre FPGA (Field Programmable Gate Array).

2.1 Códigos LDPC

Os códigos LDPC foram desenvolvidos por Gallager na década de 1960 [3], mas permaneceram

esquecidos devido ao fato de sua complexa implementação estar além das capacidades computacionais

da época.

Eles foram redescobertos por MacKay na década de 1990 [3], e, atualmente, vêm recebendo

muita atenção, por ser o código corretor de erro que mais se aproxima do limite teórico de Shannon [4].

Tal fato levou os códigos LDPC a serem utilizados como o código padrão do WIMAX e da norma Wi-

Fi 802.11n e 802.11ac [5].

Os códigos LDPC são códigos lineares de bloco gerados a partir de uma matriz de verificação

de paridade H esparsa, ou seja, com baixa quantidade de 1s em relação ao número de 0s. Um código

LDPC (n, k) é caracterizado por uma matriz H de n colunas e n-k linhas.

De acordo com a construção desta matriz de verificação de paridade, os códigos LDPC podem

ser classificados em regulares, quando a matriz H possui quantidade constante de 1s para suas linhas e

colunas, ou irregulares, caso a matriz H não tenha esta característica. Códigos irregulares provaram ter

melhor desempenho que códigos regulares, apesar de sua maior complexidade de implementação e

decodificação [3].

2.1.1 Representação gráfica de códigos LDPC

Os códigos LDPC são comumente apresentados em sua forma gráfica, conhecida como grafos

de Tanner [3], que auxilia na visualização da implementação da decodificação destes códigos.

Grafos de Tanner são grafos bipartidos obtidos a partir da matriz de verificação de paridade H

Page 23: Um estudo sobre a construção, desempenho e …

23

de um código de bloco linear. Para um código LDPC de dimensões (n, k), seu grafo de Tanner possui n

nós de variável correspondentes às colunas da matriz H, e n-k nós de verificação correspondentes às

linhas da matriz H. Haverá conexão entre o nó de verificação �� e o nó de variável �� sempre que um

elemento ℎ(�, �) da matriz de H for igual a 1, sendo j correspondente à linha e i à coluna.

Na Figura 2.1 é apresentada uma matriz de verificação de paridade para um código de bloco (8,

4) e seu grafo de Tanner correspondente.

Figura 2.1 – Exemplo de um gráfico de Tanner para um código LDPC (8, 4).

2.1.2 Construção de códigos LDPC

Quanto à sua construção, os códigos LDPC podem ser classificados em regulares ou irregulares

e em estruturados ou aleatórios. Um código é dito regular quando todas as linhas de sua matriz H

possuem a mesma quantidade 46 de uns e todas as colunas possuem a mesma quantidade 45 de uns; o

código é dito irregular quando isto não é observado. Um código é dito estruturado quando as conexões

entre os nós do grafo de Tanner dadas pelos elementos da matriz H seguem determinado padrão

geométrico ou algébrico; o código é aleatório quando esta lei definindo conexões entre os nós não

existe.

Um dos principais conceitos que deve ser levado em conta na construção da matriz H de um

código LDPC é o girth desta matriz. Ele é definido como o menor número de transições necessárias

para se sair de um nó e retornar a ele. Matrizes de verificação de paridade com girth pequeno devem

ser evitadas, pois códigos LDPC cuja matriz H possui esta característica não possuem bom

desempenho [3]. A Figura 2.2 apresenta um exemplo de um código com girth igual a 4.

Page 24: Um estudo sobre a construção, desempenho e …

24

Figura 2.2 – Exemplo de uma matriz H com girth igual a 4 e seu respectivo gráfico de Tanner.

Códigos cuja matriz H é construída de forma aleatória alcançam melhor desempenho do que

códigos estruturados, porém são mais difíceis de serem implementados e sua decodificação é mais

complexa [3]. Assim, devido à facilidade de implementação dos códigos estruturados, a presente

dissertação faz uso destes. Na seção 2.1.2.1, uma classe especial de códigos LDPC binários, irregulares

e estruturados é discutida.

2.1.2.1 Códigos LDPC binários, irregulares e estruturados

Existem vários métodos de gerar a matriz H de um código LDPC. Na presente dissertação, a

matriz de verificação de paridade foi gerada a partir do agrupamento de submatrizes obtidas através do

deslocamento cíclico à direita das colunas de uma matriz identidade [6]. As vantagens dos códigos

assim gerados são a possibilidade de construir códigos com taxas múltiplas apenas modificando a

quantidade de submatrizes agrupadas e a facilidade de criação da matriz H.

A Figura 2.3 mostra como as submatrizes circulantes são geradas através do deslocamento

cíclico de uma matriz identidade de ordem 8, �=. O índice l da submatriz indica a ordem da matriz

identidade da qual ela foi gerada e o índice j, por sua vez, indica quantas colunas foram deslocadas

ciclicamente à direita a fim de se obter a submatriz circulante Cl,j . Para valores de j maiores que l, a

matriz identidade é rotacionada de j mod l.

Page 25: Um estudo sobre a construção, desempenho e …

25

Figura 2.3 – Matrizes circulantes obtidas a partir da rotação de I8.

Os códigos IE-LDPC construídos tiveram sua matriz H construída da seguinte forma. Seja *+ o

conjunto formado pelos números primos naturais. Os valores do conjunto *+ foram utilizados para

definir as matrizes circulantes obtidas através da rotação da matriz identidade, que serve de elemento-

base da matriz H do código IE-LDPC. Valores primos foram utilizados para gerar as matrizes

circulantes, pois, desta forma, é mais provável que a matriz de verificação de paridade gerada não tenha

ciclos ou girths pequenos [7].

A Figura 2.4 mostra o exemplo de como uma matriz H de um código IE-LDPC (32, 16) é

construída por meio do agrupamento de submatrizes circulantes obtidas através da rotação de uma

matriz identidade de ordem l = 8. Note que as submatrizes circulantes foram geradas utilizando-se os

quatro primeiros elementos do conjunto *+. Note também que a matriz H construída do código IE-

LDPC é irregular e também é formada por uma matriz identidade de ordem igual a 16, �>?. A matriz H

do código IE-LDPC é construída tendo uma matriz identidade com submatriz para simplificar a

codificação do código gerado a partir dela.

Page 26: Um estudo sobre a construção, desempenho e …

26

Figura 2.4 – Matriz de verificação de paridade de um código IE-LDPC (32, 16).

A Figura 2.5 mostra como a matriz H de um código IE-LDPC (24, 16) também foi construída a

partir de uma matriz identidade de ordem l = 8.

Figura 2.5 – Matriz de verificação de paridade de um código IE-LDPC (24, 16).

Page 27: Um estudo sobre a construção, desempenho e …

27

As matrizes de verificação de paridade dos códigos IE-LDPC (32, 16) e IE-LDPC (24, 16)

poderiam ter sido construídas tendo como elemento-base uma matriz identidade de ordem diferente,

l = 6, por exemplo. Assim, por causa dessa possibilidade de várias formas de construção da matriz de

verificação de paridade de um código IE-LDPC, só é possível determinar qual matriz H vai gerar um

código com melhor desempenho através de simulações.

2.1.3 Codificação

A codificação de códigos LDPC é realizada através de multiplicação de matrizes. A codificação

é realizada obtendo-se a matriz geradora, G, de um código LDPC a partir da matriz de verificação de

paridade deste código. A palavra codificada, c, é então derivada a partir da palavra m conforme descrito

na equação (2.1).

= @A (2.1)

Tradicionalmente, a matriz geradora de um código LDPC é obtida a partir da matriz de

verificação H. Utilizando-se o método de eliminação de Gauss-Jordan, uma nova matriz, ��, é derivada

da matriz H de tal forma que ela se apresente sob o formato sistemático descrito na equação (2.2), onde ,� é a transposta da submatriz de paridade do código LDPC e �(� �) é a matriz identidade de ordem (n-

k).

�� = [�(� �) ,�] (2.2)

A partir da matriz P, a matriz geradora G é obtida através da equação

A = [, ��]. (2.3)

A matriz de verificação de paridade H do código LDPC é esparsa, mas a matriz geradora G do

código LDPC geralmente não tem esta propriedade e, além disso, mesmo a matriz H tendo todas as

suas linhas linearmente independentes, isso pode não ocorrer com a matriz G. A consequência disso é

que a implementação do codificador do código LDPC utilizando a matriz G obtida a partir do método

de eliminação de Gauss-Jordan exige a realização de um número elevado de operações e pode levar a

um código de baixo desempenho quando as linhas desta matriz não são linearmente independentes.

Para evitar o processo de se obter a matriz G a partir da matriz H utilizando-se o método de

eliminação de Gauss-Jordan, alguns códigos LDPC modernos têm sido construídos conforme descrito

na seção 2.1.2.1 [6], onde a matriz de verificação de paridade H é construída de forma a já ser

Page 28: Um estudo sobre a construção, desempenho e …

28

constituída por uma matriz identidade de ordem (n-k) e pela submatriz C, como descrito na equação

(2.4).

� = [�(� �) E] (2.4)

A submatriz C é formada por submatrizes circulantes e é igual à transposta da matriz paridade P,

sendo, desta forma, a matriz G obtida com facilidade.

2.1.4 Decodificação

Quando Gallager introduziu os códigos LDPC, ele também apresentou um algoritmo para a

decodificação destes códigos denominado algoritmo soma-produto. Diferentemente dos códigos BCH e

Reed-Solomon que possuem soluções algébricas para decodificação, os códigos LDPC são

decodificados a partir da troca de mensagens entres os nós de variável e de verificação do grafo de

Tanner deste código LDPC. Os nós de verificação estimam a probabilidade de que uma dada equação

de verificação de paridade é satisfeita dadas as estimativas recebidas dos nós de variáveis. Os nós de

variáveis, por sua vez, estimam a probabilidade de que um dado bit seja 0 ou 1 na palavra decodificada

através das probabilidades recebidas dos nós de verificação.

O algoritmo de decodificação é dividido em cinco etapas: inicialização, passo horizontal, passo

vertical, determinação da palavra LDPC decodificada e cálculo da síndrome da palavra decodificada.

Geralmente este algoritmo é apresentado no domínio logarítmico para evitar erros de arredondamento

nos cálculos das probabilidades, já que as multiplicações são transformadas em somas. A seção 2.1.4.1

apresenta e detalha o funcionamento e etapas do algoritmo soma-produto (SP).

2.1.4.1 Algoritmo soma-produto (SP)

Antes de descrever este algoritmo, as seguintes notações serão introduzidas. 3� = conjunto dos nós de variável conectados ao nó de verificação ��. 3�\� = conjunto de nós de variável conectados ao nó de verificação �� excetuando o nó de

variável ��. � = conjunto de nós de verificação conectados ao nó de variável ��.

Page 29: Um estudo sobre a construção, desempenho e …

29

�\� = conjunto de nós de verificação conectados ao nó de variável �� excetuando o nó de

verificação ��. -� = Pr (�� = 1|1�) , probabilidade de que o i-ésimo bit recebido seja 1, dado que 1� foi

recebido. &�� = mensagem de nó de variável �� para o nó de verificação ��. '�� = mensagem do nó de verificação �� para o nó de variável ��. �� = Pr (F�|1) = Probabilidade a posteriori para cada nó de variável ��.

As etapas do algoritmo soma-produto são descritas logo a seguir.

a) Inicialização

Os valores iniciais de probabilidade são obtidos a partir da palavra y recebida pelo

decodificador e da característica do canal, conforme as equações (2.5) e (2.6), onde 1� é o valor do bit

da palavra recebida e ;< é o variância do ruído do canal em que o dado foi transmitido.

&��(0) = 11 + G( <HI JK⁄ ) (2.5)

&��(1) = 11 + G(<HI JK⁄ ) (2.6)

b) Passo Horizontal: Atualização dos nós de verificação

No passo horizontal ocorre a atualização do valor de '��, que é a mensagem enviada do nó de

verificação �� para o nó de variável ��. A Figura 2.6 mostra como ocorre a troca de mensagens entre os

nós de variável e de verificação para o grafo de Tanner de uma matriz de verificação de paridade H. O

nó de verificação �� vai enviar uma mensagem ao nó de variável �� , baseando-se nas mensagens

recebidas de todos os nós de variável conectados a ele, excetuando-se ��.

Page 30: Um estudo sobre a construção, desempenho e …

30

Figura 2.6 – Passo Horizontal da decodificação LDPC.

Os valores de ('��) são atualizados de acordo com as equações (2.7) e (2.8).

'��(0) = 12 + 12 N (1 − &�P�(1))�P∈RS\I

(2.7)

'��(1) = 1 − '��(0) (2.8)

c) Passo vertical: Atualização dos nós de variável

No passo vertical ocorre a atualização do valor de &��, que é a mensagem enviada do nó de

variável �� para o nó de verificação �� . A Figura 2.7 ilustra a troca de mensagens entre os nós de

verificação e variável para o grafo de Tanner de uma matriz de verificação de paridade H. O nó de

variável �� envia ao nó de verificação �� uma mensagem obtida através das mensagens recebidas de

todos os nós de verificação conectados a ele, excetuando-se o nó �� .

Figura 2.7 – Passo Vertical da decodificação LDPC.

Os valores de &�� são atualizados utilizando-se as equações (2.9), (2.10) e (2.11).

Page 31: Um estudo sobre a construção, desempenho e …

31

&��(0) = !��(1 − -�) N ('�P�(0))�P∈TI\S (2.9)

&��(1) = !��-� N ('�P�(1))�P∈TI\S (2.10)

A constante !�� é o fator de normalização para garantir que a equação (2.11) seja observada.

&��(0) + &��(1) = 1 (2.11)

d) Obtenção da palavra decodificada

Nesta etapa acontece a atualização das probabilidades a posteriori ��(0) e ��(1), para cada nó

de variável �� . É a partir destas probabilidades que uma palavra LDPC decodificada é obtida. As

equações logo abaixo são empregadas nesta etapa. A constante !� é o fator de normalização para

garantir que a equação (2.14) seja satisfeita

��(0) = !�(1 − -�) N '��(0)�∈TI (2.12)

��(1) = !�-� N '��(1)�∈TI (2.13)

��(0) + ��(1) = 1 (2.14)

A palavra LDPC decodificada é obtida através da equação (2.15), onde �̂(�) é o bit i da palavra

decodificada.

�̂(�) = U1, VG ��(1) > 0.50, �YVZ�Z[\'á'�Z (2.15)

e) Verificação

Nesta etapa, o decodificador verifica se síndrome da palavra decodificada é nula. Isto é

realizado através da equação (2.16), onde ̂ é a palavra decodificada, �� é a transposta da matriz de

verificação de paridade e s é o vetor de dimensão (1 x k) que corresponde à síndrome da palavra

decodificada.

^ = ̂�� (2.16)

Caso a síndrome não seja nula, o processo de decodificação continua até que determinado

número de iterações seja atingido. Várias iterações são utilizadas a fim de possibilitar uma

decodificação com menor probabilidade de erro.

Page 32: Um estudo sobre a construção, desempenho e …

32

As etapas da decodificação LDPC utilizando-se os algoritmos soma-produto estão descritas na

Figura 2.8.

Figura 2.8 – Fluxograma da decodificação LDPC.

O algoritmo soma-produto é bastante preciso, mas tem como ponto negativo o fato de sua

implementação possuir muitas multiplicações, tornando onerosa sua implementação em hardware e

causando rápida saturação dos valores das probabilidades calculadas.

Por causa disso, versões modificadas deste algoritmo, o algoritmo soma-produto utilizando

razões logarítmicas (log-SP) e o algoritmo soma-mínimo (SM), são comumente utilizadas. As seções

2.1.4.2 e 2.1.4.3 descrevem estes algoritmos, respectivamente.

2.1.4.2 Algoritmo soma-produto utilizando razões logarítmicas (log-SP)

A vantagem do algoritmo log-SP sobre o algoritmo SP é que as multiplicações existentes neste

Page 33: Um estudo sobre a construção, desempenho e …

33

último algoritmo são transformadas em somas, cuja implementação é simples em hardware. Este

algoritmo trabalha com o logaritmo da razão de verossimilhança das razões das probabilidades

conforme as equações (2.17), (2.18), (2.19) e (2.20).

�(��) = ln(-'(�� = 0 1�⁄ )-'(�� = 1 1�⁄ )) (2.17)

�(&��) = ln(&��(0)&��(1)) (2.18)

�('��) = ln('��(0)'��(1)) (2.19)

�(��) = ln(��(0)��(1)) (2.20)

A variável �(��) é o logaritmo da razão de verossimilhança da informação intrínseca recebida

pelo decodificador, �(&��) é o logaritmo da razão de verossimilhança da mensagem enviada do nó de

variável �� para o nó de verificação ��, �('��) é o logaritmo da razão de verossimilhança da mensagem

enviada do nó de verificação �� para o nó de variável �� e �(��) é o logaritmo da razão de

verossimilhança da probabilidade a posteriori para cada nó de variável ��. As etapas deste algoritmo são as mesmas do algoritmo soma-produto descritas na Figura 3.8.

a) Inicialização

A inicialização dos valores de �(��) e �(&��) para os canais do tipo AWGN (Additive White

Gaussian Noise) é dada pela equação (2.21), onde 1� é o valor do bit do sinal recebido e ;< é o

variância do ruído do canal em que o dado foi transmitido.

�(&��) = �(��) = 21� ;<⁄ (2.21)

b) Passo Horizontal: Atualização dos nós de verificação

Nesta etapa ocorre a atualização de �('��), mensagem enviada dos nós de verificação para os

nós de variável. O valor de �9'��: é calculado a partir da equação (2.22), sendo a(F), 7�� e 8�� dados,

respectivamente, pelas equações (2.23), (2.24) e (2.25), onde 7�� é o sinal do valor de �(&��) e 8��, a

magnitude de �(&��).

�9'��: = N 7�b��b∈RS\I. a( c a(8�P�)�P∈RS\I

) (2.22)

Page 34: Um estudo sobre a construção, desempenho e …

34

a(F) = −ln(tanh(F 2⁄ )) = ln(Gg + 1Gg − 1) (2.23)

7�� = V��[[�(&��)] (2.24)

8�� =∣ �(&��) ∣ (2.25)

c) Passo vertical: Atualização dos nós de variável

Nesta etapa acontece a atualização de �(&��), mensagem enviada dos nós de variável para os nós

de verificação. O cálculo de �(&��) é feito de acordo com a equação (2.26).

�(&��) = �(��) + c �('�P�)�P∈TI\S (2.26)

d) Obtenção da palavra decodificada

A atualização de �(��), logaritmo da razão de verossimilhança da probabilidade a posteriori

para cada nó de variável ��, é dada pela seguinte equação (2.27) e é através dos valores de �(��) que a

decisão da palavra decodificada é realizada. O bit da palavra decodificada, �̂(�), é obtido através da

equação (2.28).

�(��) = �(��) + c �('��)�∈TI (2.27)

�̂(�) = { 1, VG�(��) < 00, �YVZ�Z[\'á'�Z (2.28)

e) Verificação

Esta etapa é semelhante à verificação realizada no algoritmo no SP, sendo calculada a síndrome

da palavra decodificada.

Outra vantagem do algoritmo log-SP sobre o algoritmo SP é que este algoritmo não necessita

calcular as constantes !�� e !�, que são utilizadas no algoritmo soma-produto.

Page 35: Um estudo sobre a construção, desempenho e …

35

2.1.4.3 Algoritmo soma-mínimo (SM)

O algoritmo soma-mínimo não é nada mais do que uma simplificação do algoritmo log-SP. Esta

simplificação ocorre na atualização do valor de �('��), dado pela equação (2.22).

A simplificação acontece devido ao fato de a função a(F) ser mais influenciada pelo menor

valor de 8��, como mostrado em (2.29). Por causa disso, a atualização do valor de �('��) passa a ser

obtida através da equação (2.30).

a(c a(8�P�)�P ) ≈ (a(a(min�P 8�P�))) = min�P∈RS\I 8�P� (2.29)

�('��) = ( N 7�P��P∈RS\I) ⋅ min�P∈RS\I 8�P� (2.30)

Outra vantagem do algoritmo soma-mínimo é que, para um canal BI-AWGN (Binary Input

Additive White Gaussian Noise), não é necessário conhecer as características do canal em que o dado

foi transmitido para obter o valor inicial de �(&��) [8]. Desta forma, a inicialização de �9&��: é mais

simples e é dada pela equação (2.31).

�9&��: = �(��) = 1� (2.31)

As demais etapas do algoritmo soma mínimo são idênticas às etapas do algoritmo log-SP e

também seguem o fluxograma descrito na Figura 2.8.

O algoritmo soma-mínimo perde em precisão para os demais algoritmos, mas sua

implementação em FPGA é bem mais simples e utiliza menor quantidade de elementos lógicos. Por isto,

ele foi escolhido para ser o algoritmo de decodificação LDPC implementado em hardware na presente

dissertação.

2.2 FPGA - Field-Programmable Gate Array

As primeiras FPGAs foram criadas na década de 80 [9], e, desde então, seu uso e aplicação em

projetos eletrônicos só tem aumentado. A grande vantagem do uso de FPGAs está no fato de ser

possível mudar parâmetros de um circuito eletrônico sem ser necessário o desenvolvimento de uma

Page 36: Um estudo sobre a construção, desempenho e …

36

nova placa eletrônica. Tal maleabilidade permite um tempo mais curto de projeto para um produto,

gerando mais ganhos às empresas que utilizam a tecnologia.

As primeiras FPGAs possuíam apenas portas lógicas simples (AND, OR, XOR, etc)

interconectadas por trilhas de ligação. A Figura 2.9 mostra como uma função lógica de um circuito

digital era obtida a partir de diferentes conexões entre as trilhas de uma FPGA existente na década de

80.

Figura 2.9 – Conjunto de trilhas e portas lógicas de FPGA antiga.

As FPGAs atuais são constituídas por células lógicas que congregam flip-flops e LUTs (look-up

tables), bem como por blocos de memória, blocos de processamento digital de sinais e PLLs (phase-

looked loops). A Figura 2.10 detalha uma FPGA e alguns de seus componentes: trilhas de conexão

(PROGRAMMABLE INTERCONNECT), blocos lógicos (LOGIC BLOCKS) e interfaces de entrada e

saída (I/O BLOCKS).

Page 37: Um estudo sobre a construção, desempenho e …

37

Figura 2.10 – FPGA e seus componentes internos [10].

Quando as FPGAs começaram a ser utilizadas, as conexões entre suas trilhas eram feitas

manualmente. Atualmente, as conexões entre blocos lógicos são feitas via software. Um componente é

descrito utilizando-se alguma linguagem de descrição de hardware tal como VHDL ou Verilog e, em

seguida, o software que realiza a síntese da lógica na FPGA utiliza os blocos lógicos nela existentes e

realiza as interconexões necessárias entre estes blocos lógicos, a fim de implementar o componente

eletrônico criado.

No projeto de circuitos utilizando FPGA, três fatores são relevantes: potência elétrica dissipada,

área ocupada (número de elementos lógicos utilizados) e frequência máxima de operação. Como a ideia

inicial desta dissertação não é desenvolver um produto, mas sim, implementar e comprovar conceitos,

tanto a potência dissipada como a área ocupada na FPGA não foram levados em consideração. O fator

que mais influenciou a implementação do codificador e do decodificador dos códigos IE-LDPC

construídos foi a frequência máxima de operação do projeto, já que isto permite que o circuito opere

com menos paralelismo nas operações matemáticas que vai realizar.

Para finalizar, vale ressaltar que o uso de FPGAs também possui algumas desvantagens.

Quando em projetos utilizando muitos elementos lógicos, a interconexão entre estes elementos dentro

da FPGA pode estar distante, causando atrasos que influenciam negativamente na frequência máxima

de operação. Para casos como estes, e estando o projeto já consolidado, costuma-se construir chips

específicos, denominados ASIC (Application Specific Integrated Circuit), de tal forma a criar o projeto

Page 38: Um estudo sobre a construção, desempenho e …

38

com blocos lógicos próximos entre si, e não com a distância determinada pela FPGA.

A presente dissertação utilizou a FPGA Virtex-5 XC5VLX50T da Xilinx para a implementação

de códigos IE-LDPC em hardware. Esta FPGA foi escolhida por possuir interfaces de entrada e saída

de alta velocidade, ideais para trabalhar com comunicações digitais em altas taxas. Já o software que

realiza a síntese na FPGA do codificador e do decodificador descritos em VHDL é o ISE WebPACK da

Xilinx.

A Figura 2.11 detalha uma célula básica da FPGA utilizada. Esta célula básica possui duas LUTs,

dois flip-flops D e interfaces de conexão com outras células básicas.

Figura 2.11 – Célula básica da Virtex-5 [10].

2.3 Códigos corretores de erro para comunicações ópticas

Códigos corretores de erro, como o LDPC, são utilizados com o propósito de atenuar os efeitos

das interferências presente em um canal sobre os dados transmitidos. No caso de comunicações ópticas,

Page 39: Um estudo sobre a construção, desempenho e …

39

as causas das interferências no canal podem ser: atenuação do sinal óptico, dispersão cromática,

dispersão do modo de polarização e distorção do pulso óptico devido a não-linearidades da fibra óptica,

que é o canal de comunicação [1].

O uso de códigos corretores de erro em comunicações ópticas associados a um processo de

modulação permite o aumento da capacidade de transmissão pelo canal óptico e o aumento do alcance

do sinal óptico transmitido, reduzindo-se, dessa forma, o número de repetidores empregados, gerando

economia na implementação de laços ópticos. Além disso, esta composição de códigos corretores de

erro com modulação possibilita que sistemas de comunicações ópticas operem em taxas acima de 40

Gbps [1], uma vez que a influência da interferência entre símbolos no detector óptico é minimizada.

A Figura 2.12 descreve um sistema de comunicações ópticas em que códigos corretores de erro

associado a um processo de modulação são utilizados.

Figura 2.12 – Diagrama de um sistema de comunicações ópticas.

Page 40: Um estudo sobre a construção, desempenho e …

40

A fonte é o dispositivo que gera a informação a ser transmitida pelo equipamento de

telecomunicações, ou seja, a fonte gera sequências de informação binárias em sua saída.

A codificação de fonte, por sua vez, é um processo de compressão da informação gerada pela

fonte que retira as redundâncias e/ou as irrelevâncias desta informação de tal forma a reduzir ao

máximo possível a quantidade de bits transmitidos, sem comprometer a integridade da informação.

A codificação de canal, por outro lado, é o processo que introduz bits redundantes à informação

a ser transmitida, de tal forma a permitir que o receptor utilize estes bits extras para detectar e corrigir

erros produzidos durante a transmissão através do canal.

Em comunicações ópticas a codificação de canal é realizada empregando-se códigos corretores

de erro, tais como, o RS(255, 239) especificado pela norma ITU-T G.709 e os códigos BCH(3860,

3824) e BCH(2040, 1930) especificados pela norma ITU-T G.975.1. O escopo desta dissertação se

situa na codificação de canal.

A modulação é um processo de mapeamento da informação binária em um sinal adequado a ser

transmitido pelo canal de comunicação. Isso pode implicar na taxa de transmissão do sistema de

comunicação. Em comunicações ópticas podem ser utilizadas modulações na intensidade do sinal

transmitido ou na fase e frequência do sinal óptico. Atualmente as modulações coerentes mais

utilizadas são QAM (Quadrature Amplitude Modulation) e PSK (Phase Shift Keying) [1].

Além de modulação, os sinais ópticos podem ser multiplexados, ou seja, pode-se transmitir

vários sinais distintos dentro de uma fibra. Os sistemas multicanais utilizam multiplexagem por divisão

no comprimento de onda, WDM (Wavelength Division Multiplexing) e também OFDM (Orthogonal

Frequency-Division Multiplexing) [1].

A demodulação é o processo de caracterizar estatisticamente o sinal recebido e decidir, dentro

de um conjunto finito, qual a sequência de formas de ondas transmitidas. Após tomar esta decisão, o

receptor óptico usa um mapeamento inverso em relação ao usado pelo modulador para determinar a

sequência de símbolos discretos na saída do receptor óptico.

O receptor óptico sem modulação consiste de apenas um fotodiodo, que é responsável por

converter o sinal do domínio óptico para o domínio elétrico, e por circuitos eletrônicos apropriados

para amplificar o sinal antes de entregar a informação para o destino. Em sistemas ópticos

convencionais usa-se detecção direta, já que a informação é transmitida na intensidade do sinal. Em

sistemas mais modernos, para aumentar a eficiência espectral, ocorre detecção coerente.

A decodificação de canal é o processo de utilizar a redundância adicionada pela codificação de

Page 41: Um estudo sobre a construção, desempenho e …

41

canal para controlar os efeitos dos ruídos e distorções causados pela transmissão do dado através do

canal. Já a decodificação de fonte, por sua vez, é o processo de reinserir a redundância removida pelo

codificador de fonte.

2.3.1 Interface óptica-elétrica para utilizar códigos LDPC em comunicações ópticas

Para utilizar os códigos LDPC em comunicações ópticas, é necessária uma interface que

converta o sinal do domínio óptico para o domínio elétrico e vice-versa. Além disso, para operar com

códigos LDPC, esta interface necessita trabalhar com valores reais, representados por um conjunto de

bits, e não valores binários 0 ou 1.

Quando códigos LDPC são empregados em comunicações ópticas, esta interface amostra e

quantiza o sinal óptico, convertendo-o em um sinal elétrico constituído por p conjuntos de q bits, onde

p é o fator de paralelismo empregado e q é a quantidade de bits empregados para quantizar o valor do

sinal óptico.

A quantização é realizada baseando-se na intensidade luminosa do sinal óptico, quando a

detecção do sinal óptico é por intensidade, ou na fase e amplitude do sinal óptico, quando a detecção

coerente é empregada.

Como a decodificação do código LDPC utiliza decisão suave (soft-decision), na presente

dissertação, o valor do sinal óptico é quantizado por um conjunto de 12 bits que correspondem a um

valor real no intervalo [-1,1]. Nestes 12 bits, o bit mais significativo representa o sinal do número, os 7

bits seguintes, sua parte inteira, e os 4 bits restantes, sua parte fracionária.

A implementação dos códigos LDPC utilizou a representação em ponto fixo, pois a

representação em ponto flutuante é muito complexa de ser implementada em FPGA. O tamanho da

parte inteira, 7 bits, foi escolhido de tal forma a impedir a saturação das somas que ocorrem no

algoritmo de decodificação soma-mínimo (SM). Já os 4 bits da parte fracionária foram escolhidos de

forma a garantir uma precisão mínima de 0.075 na quantização dos valores do sinal óptico. A Figura

2.13 detalha a notação em ponto fixo empregada na presente dissertação.

Page 42: Um estudo sobre a construção, desempenho e …

42

Figura 2.13 – Notação em ponto fixo empregada na presente dissertação.

A Figura 2.14 ilustra uma interface óptica-elétrica trabalhando com sinais ópticos de diferentes

taxas (2,5 Gbps, 10 Gbps ou 40 Gbps) e sinais elétricos formados por 16, 64 ou 256 conjuntos de 12

bits, respectivamente.

Figura 2.14 – Interface óptica-elétrica.

Page 43: Um estudo sobre a construção, desempenho e …

43

Outras taxas de paralelismo na conversão óptica-elétrica poderiam ser empregadas. O sinal

óptico de 2,5 Gbps, por exemplo, poderia ser transformado em um sinal elétrico formado por 8

conjuntos de 12 bits. Entretanto, com esta taxa de paralelismo, o codificador e o decodificador LDPC

teriam que operar com o dobro da frequência necessária para quando se trabalha com a taxa de 16

conjuntos de 12 bits.

A escolha de uma menor taxa de paralelismo implica na necessidade de se operar em

frequências maiores. Por outro lado, quanto maior for a taxa de paralelismo, maior será a quantidade de

LUTs utilizadas no projeto, influenciando negativamente na quantidade de elementos lógicos utilizados.

Assim, é necessário encontrar o ponto ótimo entre taxa de paralelismo e quantidade de elementos

lógicos utilizados.

A Virtex-5, FPGA utilizada na presente dissertação, tem frequência máxima de operação da

ordem de grandeza de centenas de MHz e só é possível utilizá-la para processar sinais de ordem de

Gbps porque ocorre o processamento em paralelo de vários bits em um pulso de relógio. Por exemplo,

para se processar um sinal de taxa de 2,5 Gbps, uma das opções possíveis é processar 16 conjuntos de

12 bits a cada pulso de relógio, fazendo com que a FPGA trabalhe a uma frequência de 156,25 MHz.

A Figura 2.15 ilustra como ocorre o fluxo dos sinais ópticos e elétricos através das interfaces e

dentro da FPGA.

Figura 2.15 – Visão global do contexto em que o codificador e decodificador LDPC é empregado.

Page 44: Um estudo sobre a construção, desempenho e …

44

3 IMPLEMENTAÇÃO

Este capítulo descreve a implementação em VHDL do codificador e o decodificador de códigos

IE-LDPC. Antes desta descrição, são apresentadas as influências da FGPA utilizada, Virtex-5, no

desenvolvimento do codificador e do decodificador dos códigos IE-LDPC construídos.

3.1 Influências dos componentes da Virtex-5 na implementação do codificador e do

decodificador IE-LDPC

A implementação de um projeto em FPGA é determinada pelos seus componentes. Nas seções a

seguir são descritos os componentes internos da Virtex-5, FPGA utilizada na presente dissertação, que

mais influenciaram na implementação do codificador e do decodificador dos códigos IE-LDPC

construídos.

A Figura 3.1 detalha a Virtex-5 e seus principais componentes: DLL (Delay-locked Loop),

circuito similar ao PPL (Phase-locked Loop), com a diferença de o oscilador controlado por tensão é

substituído por uma linha de atraso; CLB (Configurable Logic Blocks), parte da FPGA que armazena as

células lógicas e flip-flops; BLOCK RAM (Random Access Memory), banco de memórias internas da

FPGA e I/O LOGIC, pinos de entrada e saída da FPGA.

Page 45: Um estudo sobre a construção, desempenho e …

45

Figura 3.1 – Componentes da Virtex-5 interligados por trilhas internas [10].

3.1.1 Trilhas internas e frequência máxima de operação

Os componentes da Virtex-5 são interconectados por trilhas internas, conforme indicado pela

Figura 3.2. Estas interconexões entre os elementos da FPGA faz com que qualquer circuito sintetizado

na Virtex-5 tenha frequência máxima de operação em torno de 400 MHz, que é a frequência máxima

em que seu fabricante, Xilinx, garante que o sinal de relógio que se propaga pelas trilhas internas que

ligam os flip-flops está estabilizado e os tempos de set e hold não são violados.

Porém, na prática, a frequência máxima de operação da Virtex-5 é um pouco menor. O fator

limitante é o atraso de propagação de um sinal pelo caminho combinacional entre flip-flops. Para evitar

problemas de amostragem, o período do relógio do flip-flop tem que ser maior que o atraso ocasionado

pelo caminho combinacional. Além da quantidade de portas lógicas, a distância entre elementos lógicos

influenciam negativamente na frequência máxima de operação. A Figura 3.2 exemplifica um caminho

combinacional entre flip-flops que causa impacto na frequência máxima de operação.

Page 46: Um estudo sobre a construção, desempenho e …

46

Figura 3.2 – Atraso dentro da Virtex-5 devido ao caminho combinacional.

3.1.2 Memórias internas

A Virtex-5 possui bancos de memórias, que são as block RAMs, usadas para aumentar a

velocidade da escrita e leitura de dados dentro da FPGA. Quando todas estas memórias estiverem

utilizadas ou quando não especificado pelo usuário, o programa sintetizador de lógica na Virtex-5 vai

sintetizar memórias utilizando blocos lógicos. Esta forma de síntese de memórias é conhecida como

distributed RAM e seu uso diminui a frequência máxima de operação da FPGA, pois o processo de

leitura e escrita em distributed RAMs é mais lento do que em block RAMs.

3.2 Implementação do código IE-LDPC

3.2.1 Codificador

O codificador implementa a equação (3.1), onde c é a palavra LDPC codificada, m é a palavra

Page 47: Um estudo sobre a construção, desempenho e …

47

de informação a ser codificada, G é a matriz geradora do código LDPC, P é a matriz de paridade do

código LDPC e �� é a matriz identidade de ordem k.

= @A

c = [o(1) o(2) … o(q)] [P | ��]

c = [�(1) �(2) … �([ − q)| o(1) o(2) … o(q)]

(3.1)

A implementação do codificador é simples, sendo, para códigos binários, várias portas XOR em

cascata. A Figura 3.8 mostra como o codificador foi implementado. Para o cálculo dos bits �(1) a �([ − q) da palavra codificada, o codificador usa todos os bits da sequência de informação m. Quando

o elemento g(j, 1) = 1 da matriz G, o bit m(j) entra no cálculo do bit c(j), caso contrário, não. A variável

j pertence ao conjunto [1, (n-k)] e k é o número de linhas da matriz G.

Figura 3.3 – Codificador LDPC.

3.2.2 Decodificador

O decodificador LDPC é a implementação em hardware do algoritmo soma-mínimo e é

constituído por três componentes: cálculo de �('��) , cálculo de �(&��) e decisão. Esta divisão é

relacionada às etapas do algoritmo de decodificação.

A etapa do cálculo do logaritmo da razão de verossimilhança da mensagem enviada do nó de

Page 48: Um estudo sobre a construção, desempenho e …

48

verificação �� para o nó de variável ��, �('��), ou passo horizontal, consiste na obtenção dos valores das

mensagens que os nós de verificação enviam aos nós de variável. Esta etapa recebe o nome de passo

horizontal, pois este cálculo é realizado percorrendo-se a linha da matriz H.

A etapa do cálculo do logaritmo da razão de verossimilhança da mensagem envidada do nó de

variável �� para o nó de verificação ��, �(&��), ou passo vertical, consiste na obtenção dos valores das

mensagens que os nós de variável enviam aos nós de verificação. Esta etapa recebe o nome de passo

vertical porque este cálculo é realizado percorrendo-se a coluna da matriz H.

A etapa Decisão consiste no cálculo na palavra de informação decodificada e no cálculo da

síndrome desta palavra.

Cada uma destas etapas é realizada em um pulso de relógio. Portanto, uma iteração de

decodificação de uma palavra LDPC leva três pulsos de relógio para ser realizada.

A Figura 3.4 mostra o decodificador LDPC dividido em seus blocos operacionais. O cálculo de �('��) ocorre no primeiro pulso de relógio, o cálculo de �(&��), no segundo pulso de relógio e o cálculo

da nova palavra decodificada, data_out, e de sua síndrome ocorre no terceiro e último pulso de relógio

da iteração da decodificação LDPC.

Figura 3.4 – Blocos do decodificador LDPC.

Cada valor de �(&��) e �('��) é armazenado em LUTs e representado por um conjunto de 12 bits,

conforme indicado na Figura 2.13. Não foi possível utilizar as block RAMs da FPGA, já que se estes

valores fossem armazenados nestas memórias, não seria possível efetuar a leitura e escrita de vários

endereços de memória em um mesmo pulso de relógio.

Um ponto negativo do armazenamento dos valores de �(&��) e �('��) em LUTs é que estes

valores são armazenados em células lógicas, aumentado consideravelmente a quantidade de elementos

lógicos da FPGA utilizados no projeto.

Page 49: Um estudo sobre a construção, desempenho e …

49

A implementação tradicional do decodificador LDPC verifica a cada instante se o valor de ℎ(�, �) é nulo ou não, tornando o caminho combinacional longo e lento. Por isso, optou-se por

armazenar em uma matriz, ����, os valores das colunas e das linhas para as quais ℎ(�, �) = 1, e, da

mesma forma, em outra matriz, ����, os valores das linhas e das colunas para as quais ℎ(�, �) = 1.

Trabalhando-se com a matriz H, seria necessário armazenar (k x n) valores. No entanto,

utilizando-se ���� e ����, é necessário armazenar duas matrizes de dimensões (46 x k) e (n x 45),

respectivamente. Sendo 46 o número de 1s por linha e 45 o número de 1s por coluna da matriz H.

A Figura 3.5 mostra como as matrizes ���� e ���� são obtidas a partir da matriz H. Para a

primeira linha da matriz H temos ℎ(�, �) = 1 para os seguintes valores de coluna: 2, 4, 5 e 8. Estes

valores são os elementos da primeira linha da matriz ����. Para a primeira coluna da matriz H temos ℎ(�, �) = 1 para os seguintes valores de linha: 2 e 4. Estes valores são os elementos da primeira linha da

matriz ����.

Figura 3.5 – Matrizes auxiliares obtidas a partir da matriz H.

Os itens 3.3.2.1, 3.3.2.2 e 3.3.2.3 a seguir detalham como cada componente do decodificador

LDPC foi implementado.

Page 50: Um estudo sobre a construção, desempenho e …

50

3.2.2.1 Calculador do Passo Horizontal

O passo horizontal é a etapa em que são calculados os valores de probabilidade da mensagem

que o nó de verificação �� envia para o nó de variável �� . A mensagem �('��) só existirá quando ℎ(�, �) = 1.

Esta é a etapa que mais utiliza elementos lógicos no decodificador LDPC. A grande vantagem

do algoritmo SM é que ele transforma o cálculo de �('��) na obtenção do valor mínimo do módulo de �(&��), 8�� , e na multiplicação em cascata do sinal de �(&��.), 7�� , para todos os valores de �(&��)

envolvidos no cálculo de �('��) para um valor específico de linha i e coluna j.

Como os valores de �(&��) estão em representação de complemento de 2, para se obter o

mínimo do módulo de números negativos, é necessário transformá-los em seus correspondentes valores

positivos, e, a partir daí, obter o valor de menor módulo. O circuito que obtém o sinal resultante são

várias portas lógicas XOR em sequência, lembrando que o sinal negativo tem valor lógico 1 e o

positivo, 0.

A Figura 3.6 mostra a implementação do passo horizontal. Para obter o valor de �('��), são

utilizados no cálculo os valores de �(&�P�) e 7��P, onde �P é o valor das colunas da linha j da matriz H

em que ℎ(�, �) = 1, excetuando-se a coluna i.

Page 51: Um estudo sobre a construção, desempenho e …

51

Figura 3.6 – Passo Horizontal do decodificador LDPC.

A variável �P pertence ao conjunto 3�\�, que é o conjunto formado pelas colunas da linha j em

que ℎ(�, �) = 1, excetuando-se a coluna i. Este é o conjunto dos nós de variável conectados ao nó de

verificação �� excetuando o nó de variável ��. O conjunto 3�\� tem dimensão igual a 46-1 e é formado

pelos elementos {�r, �<,..., �s6 r}, que são os valores das colunas em que ℎ(�, �) = 1, para a linha j,

excetuando-se a coluna i.

Considere a matriz de verificação de paridade H da Figura 3.5. Para a primeira linha, o conjunto

dos valores de coluna em que ℎ(�, �) = 1 é {2,4,5,8}. Assim, o cálculo do valor de �('<r) depende dos

valores de �(&rt), �(&ru) e �(&rv), e o cojunto {�r, �<,..., �s6 r} é igual a {4,5,8}.

Da mesma forma, para a terceira linha, o conjunto dos valores de coluna em que ℎ(�, �) = 1 é

{3,6,7,8}. Assim, o cálculo do valor de �('wx) depende os valores de �(&xx), �(&xy) e �(&xv) e o

conjunto {�r, �<,..., �s6 r} é igual a {3,7,8}.

O bloco módulo-mínimo da Figura 3.6 recebe como entrada 12 bits, pois ele precisa saber se o

número é negativo ou não para convertê-lo ao seu complemento de 2, e assim obter qual possui menor

módulo. O bloco concatenação, por sua vez, recebe a magnitude do menor valor do módulo de �(&��),

11 bits, e concatena com o bit de sinal, 1 bit, resultante da operação com todos os sinais de �(&��),

formando, desta forma, o valor de �('��).

Page 52: Um estudo sobre a construção, desempenho e …

52

3.2.2.2 Calculador do Passo Vertical

O passo vertical é a etapa em que são calculados os valores de probabilidade da mensagem que

o nó de variável �� envia para o nó de verificação ��. A mensagem �(&��) só existirá quando ℎ(�, �) = 1.

Cada valor de �(&��) é obtido pela soma de valores de �('��) e do valor de �(��), que é o valor

inicial da probabilidade da palavra recebida do canal. Consequentemente, este bloco foi implementado

com somadores em cascata, sendo que cada somador armazena um conjunto de 12 bits, conforme

descrito na Figura 2.13.

Como o calculador de �(&��) é um acumulador, o dado foi projetado com parte inteira de 7 bits

para evitar saturação. A soma foi implementada com complemento de 2, tendo valores no intervalo

[−128,127], sendo que o valor da soma é protegido contra overflow e underflow. Se a soma exceder o

valor de 127, ou se ela for inferior a -128, este valor é armazenado.

A Figura 3.7 ilustra a implementação do calculador dos valores �(&��) . O bloco somador

executa a soma de valores de 12 bits no intervalo [-128,127] e �(��) é o valor inicial da probabilidade

da palavra recebida do canal. O cálculo dos valores de �(&��) é realizado para um valor fixo i, que

representa a coluna percorrida durante o passo vertical.

Figura 3.7 – Passo Vertical do decodificador LDPC.

A variável �P pertence ao conjunto �\� , que é o conjunto formado pelos valores de linha da

coluna i em que ℎ(�, �) = 1 , excetuando-se a linha j. Este é o conjunto dos nós de verificação

conectados ao nó de variável �� excetuando o nó de verificação ��. O conjunto �\� tem dimensão igual

Page 53: Um estudo sobre a construção, desempenho e …

53

a 45-1 e é formado pelos elementos {�r, �<,..., �s5 r}, que são os valores das colunas em que ℎ(�, �) =1, para a linha j, excetuando-se a coluna i.

Considere a matriz de verificação de paridade H da Figura 3.5. Para a primeira coluna, o

conjunto dos valores de linha em que ℎ(�, �) = 1 é {2,4}. Assim, o cálculo do valor de �(&r<) depende

dos valores de �('tr) e �(�r), e o conjunto {�r, �<,..., �s5 r} é igual a {4}.

Da mesma forma, para a sexta coluna, o conjunto dos valores de linha em que ℎ(�, �) = 1 é

{2,3}, Assim, o cálculo do valor de �(&wx) depende os valores de �('w<) e �(�w), e o conjunto {�r, �<,..., �s6 r} é igual a {2}.

3.2.2.3 Decisão

Este bloco é responsável pelo cálculo do logaritmo da razão de verossimilhança da

probabilidade a posteriori para cada nó de variável ��, �(��), pela obtenção da palavra decodificada e

pelo cálculo da síndrome desta palavra.

O valor de �(��) é obtido através da soma de todos os valores �('��) em que ℎ(�, �) = 1 para

determinada coluna i. A Figura 3.8 descreve como o calculador de �(��) foi implementado. A variável �P pertence ao conjunto � , que é o conjunto formado pelos valores de linha da coluna i em que ℎ(�, �) = 1. Este é o conjunto dos nós de verificação conectados ao nó de variável ��. O conjunto � tem dimensão igual a 45 e é formado pelos elementos {�r, �<,..., �s5}, que são os valores das colunas

em que ℎ(�, �) = 1, para a linha j.

Considere a matriz de verificação de paridade H da Figura 3.5. Para a primeira coluna, o

conjunto dos valores de linha em que ℎ(�, �) = 1 é {2,4}. Assim, o cálculo do valor de �(�r) depende

dos valores de �('<r) e �('tr) e o conjunto {�r, �<,..., �s5} é igual a {2,4}.

Da mesma forma, para a sexta coluna, o conjunto dos valores de linha em que ℎ(�, �) = 1 é

{2,3}, Assim, o cálculo do valor de �(�w) depende os valores de �('w<) e �('wx) e o conjunto {�r, �<,..., �s6} é igual a {2,3}.

Page 54: Um estudo sobre a construção, desempenho e …

54

Figura 3.8 – Calculador de �(��).

A palavra decodificada é obtida através dos valores de �(��). Cada bit da palavra-código

recebida, �̂(�), é obtido através da equação (3.2).

�̂(�) = U 1, VG �(��) < 00, caso contrário (3.2)

A implementação da equação (3.2) é simples. Verificando-se o valor do sinal de �(��), bit mais

significativo, determina-se se o valor de �̂(�) é 1 ou 0.

Uma vez decodificada a palavra-código recebida, sua síndrome é calculada. O cálculo da

síndrome ocorre através da equação (3.3) onde ̂ é a palavra-código recebida, �� é a transposta da

matriz de verificação de paridade e s é a síndrome.

} = ̂�� (3.3)

A Figura 3.13 ilustra como o calculador de síndrome foi implementado. O cálculo da síndrome é

semelhante ao codificador e consiste em portas lógicas XOR em cascata. A síndrome s é um vetor de

dimensão (1 x n-k) e seus bits, s(i), são determinados multiplicando-se o vetor ̂ com a coluna i da

matriz ��, onde n é o número de bits da palavra-código. Se existe ��(1, �), o bit �̂(�) da palavra-código

recebida entra no cálculo do bit s(i) da síndrome, caso contrário, não. A variável i pertence ao conjunto

[1,n], onde n é o número de colunas da matriz ��.

Page 55: Um estudo sobre a construção, desempenho e …

55

Figura 3.9 – Calculador de síndrome do decodificador LDPC.

Na implementação, a etapa da decisão é a etapa mais lenta do decodificador, pois realiza o

cálculo de �(��), o cálculo da palavra decodificada e de sua síndrome em um mesmo pulso de relógio.

Este bloco poderia ser executado em mais de um pulso de relógio, mas isto acarretaria em uma maior

latência no cálculo da palavra decodificada.

3.2.2.4 Propagação dos dados dentro do decodificador

A decodificação de uma palavra codificada LDPC recebida leva três pulsos de relógio para

ocorrer. No primeiro pulso de relógio acontece o cálculo dos valores de �('��), no segundo pulso de

relógio é realizada a atualização dos valores de �(&��) e no terceiro pulso de relógio é calculada a

palavra LDPC decodificada.

A Figura 3.10 ilustra como ocorre a propagação das palavras que chegam ao decodificador

LDPC. No instante t, a palavra data_in(t) chega ao decodificador e os valores de �('��) para esta

palavra são calculados. No instante t+1, enquanto a palavra data_in(t) tem seus valores de �(&��)

calculados, chega ao decodificador uma nova palavra, data_in(t+1), que tem calculados os seus valores

Page 56: Um estudo sobre a construção, desempenho e …

56

de �('��).

No instante t+2, enquanto a palavra data_in(t) tem sua palavra decodificada, data_in(t+1) seus

valores de �(&��) calculados, chega ao decodificador uma nova palavra, data_in(t+2) que tem

calculados os seus valores de �('��). No instante t+3, a palavra data_in(t) tem sua palavra decodificada, data_out(t+3), exteriorizada

pelo decodificador, a palavra data_in(t+1) tem sua palavra decodificada calculada, a palavra

data_in(t+2) tem seus valores de �(&��) calculados e a palavra que que chegou no instante t+3,

data_in(t+3), tem seus valores de �('��) calculados.

A palavra que chegou no instante t+1, data_in(t+1), tem sua palavra decodificada exteriorizada

no instante t+4, a palavra que chegou no instante t+2, data_in(t+2), tem sua palavra decodificada,

data_out_(t+5) exteriorizada no instante t+5 e assim continua o processo de decodificação. Enquanto

este processo acontece, novas palavras chegam ao decodificador e suas etapas internas continuam em

operação.

É necessário ressaltar o preço de cada iteração do decodificador LDPC. Cada iteração do

decodificador dura três pulsos de relógio, sendo necessários, portanto, três novos blocos do

decodificador para cada nova iteração. Desta forma, chega-se em um compromisso entre o aumento de

desempenho e o aumento do número de elementos lógicos. Por exemplo, um decodificador que

realizasse quatro iterações precisaria de 12 blocos básicos para funcionar.

Caso a palavra decodificada já esteja correta antes de alcançar todas as iterações, as operações

matemáticas são interrompidas, sendo o valor da palavra decodificada apenas propagado para manter o

sincronismo e a latência do decodificador.

Page 57: Um estudo sobre a construção, desempenho e …

57

Figura 3.10 – Propagação dos dados ao longo dos vários blocos do decodificador..

Page 58: Um estudo sobre a construção, desempenho e …

58

4 RESULTADOS

Neste capítulo são apresentados os resultados da comparação do desempenho de dois algoritmos

de decodificação de códigos LDPC, os algoritmos log-SP e SM, para os códigos IE-LDPC construídos.

Este capítulo também apresenta os resultados da síntese em FPGA do codificador e do decodificador

implementados para estes códigos.

4.1 Comparação do desempenho dos algoritmos de decodificação log-SP e SM para os códigos

IE-LDPC construídos

Esta seção apresenta os resultados da comparação do desempenho dos códigos IE-LDPC

construídos e decodificados com os algoritmos de decodificação log-SP e SM. Foram construídos

códigos LDPC binários, irregulares e estruturados de comprimentos (2000, 1000) e (4000, 2000). As

matrizes de verificação de paridade destes códigos foram construídas conforme descrito na seção

2.1.2.1 desta dissertação.

Os comprimentos destes códigos foram escolhidos de tal forma que, quando estes códigos

fossem sintetizados, seus codificadores e decodificadores operassem em frequências compatíveis com

operações em FPGA. Para os códigos IE-LDPC (2000, 1000) e IE-LDPC (4000, 2000) é necessário que

seus codificadores e decodificadores, quando em funcionamento em FPGA, tenham frequência de

operação de no mínimo 50 MHz e 25 MHz, respectivamente.

A comparação do desempenho foi realizada através da simulação da transmissão de dados

através de um canal AWGN, tido como uma simplificação do modelo de canal utilizado em

comunicações ópticas. A simulação foi realizada utilizando-se o software MATLAB e as palavras-

códigos transmitidas foram decodificadas iterativamente utilizando cinco iterações.

A Figura 4.1 apresenta o ambiente em que os algoritmos de decodificação tiveram seu

desempenho analisado. A sequência de informação foi gerada de forma aleatória, em seguida, foi

codificada e transmitida por um canal AWGN. Por fim, a palavra-código recebida foi decodificada e a

estimativa da sequência de informação foi comparada com a sequência de informação original a fim de

se obter a taxa de erro de bit na recepção. Tal procedimento foi realizado para diversos valores de

Page 59: Um estudo sobre a construção, desempenho e …

59

relação sinal/ruído por bit (��/()).

Figura 4.1 – Cenário da simulação dos códigos IE-LDPC.

A meta neste capítulo é ajustar a dimensão da matriz identidade que gera os códigos IE-LDPC

de forma a estreitar o intervalo entre os desempenhos dos processos de decodificação log-SP e SM. Isto

permite a escolha de códigos LDPC que associados à decodificação SM utilizem menor número de

elementos lógicos na placa FPGA com baixa perda no processo de decodificação.

4.1.1 Resultados da comparação do desempenho dos algoritmos log-SP e SM para os códigos

IE-LDPC (2000, 1000)

Quatro códigos foram construídos utilizando matriz identidade com os seguintes valores de

ordem: 50, 100, 200 e 500. As Figuras 4.2 a 4.5 mostram o desempenho dos algoritmos de

decodificação para estes códigos IE-LDPC (2000, 1000).

4.1.1.1 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 50

A forma reduzida da matriz H do código IE-LDPC (2000, 1000), gerada a partir de uma matriz

identidade de ordem igual a 50, está representada na equação (4.1).

Page 60: Um estudo sobre a construção, desempenho e …

60

� = � �u) 2u) … 2u) Eu),< Eu),x … Eu),<r2u) �u) … 2u) Eu),<x Eu),<� … Eu),<x⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2u) 2u) … �u) Eu),<r Eu),xx … Eu),tr�

(4.1)

A Figura 4.2 mostra que para este código, o ganho do algoritmo log-SP em relação ao algoritmo

SM ficou em um intervalo de amplitude igual a 1,5 dB, valor este alcançado para uma BER = 10-5.

Figura 4.2 – Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz identidade de

ordem igual a 50.

4.1.1.2 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 100

A forma reduzida da matriz H do código IE-LDPC (2000, 1000), gerada a partir de uma matriz

identidade de ordem igual a 100, está representada na equação (4.2).

� = � �r)) 2r)) … 2r)) Er)),< Er)),x … Er)),<�2r)) �r)) … 2r)) Er)),xr Er)),xy … Er)),yr⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2r)) 2r)) … �r)) Er)),wy Er)),y� … Er)),tr�

(4.2)

Para este código, conforme visto na Figura 4.3, o algoritmo SM teve desempenho 0,4 dB

Page 61: Um estudo sobre a construção, desempenho e …

61

inferior ao log-SP, para BER = 10-4.

Figura 4.3 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz identidade de

ordem igual a 100.

4.1.1.3 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 200

A forma reduzida da matriz H do código IE-LDPC (2000, 1000), gerada a partir de uma matriz

identidade de ordem igual a 200, está representada na equação (4.3).

� = � �<)) 2<)) … 2<)) E<)),< E<)),x … E<)),rr2<)) �<)) … 2<)) E<)),rx E<)),ry … E<)),<�⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2<)) 2<)) … �<)) E<)),yx E<)),y� … E<)),�y�

(4.3)

Para este código, apresentado pela Figura 4.4, a variação do desempenho do algoritmo log-SP,

em termo de relação sinal/ruído, ficou em um intervalo de 0,15 dB maior em relação ao algoritmo SM,

para uma BER = 10-4.

Page 62: Um estudo sobre a construção, desempenho e …

62

Figura 4.4 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz identidade de

ordem igual a 200.

4.1.1.4 Resultados para o código IE-LDPC (2000, 1000) gerado a partir de uma matriz

identidade de ordem igual a 500

A forma reduzida da matriz H do código IE-LDPC (2000, 1000), gerada a partir de uma matriz

identidade de ordem igual a 500, está representada na equação (4.4).

� = � �u)) 2u))2u)) �u)) Eu)),< Eu)),xEu)),u Eu)),y� (4.4)

A Figura 4.5 mostra que os dois algoritmos de decodificação têm desempenho próximos e que a

máxima diferença de desempenho entre os dois algoritmos é menor que 0,12 dB, a favor do log-SP,

para uma BER em torno de 10-4.

Page 63: Um estudo sobre a construção, desempenho e …

63

Figura 4.5 - Curvas de desempenho do código IE-LDPC (2000, 1000) gerado a partir de uma matriz identidade de

ordem igual a 500.

Dentre os códigos IE-LDPC(2000,1000) construídos, o que apresentou melhor desempenho foi

o código gerado a partir de uma matriz identidade de ordem igual a 50, alcançando uma taxa de erro

próxima a 10-6 para um relação sinal-ruído de 2 dB, quando decodificado com o algoritmo log-SP. Isso

é devido ao fato de que quanto menor a ordem da matriz identidade, maior será a quantidades de 1s por

linha e coluna e, consequentemente, maior será a quantidade de nós de variável e nós de verificação.

Por fim, uma quantidade maior de nós aumenta a precisão do cálculo dos valores das probabilidades

permutadas entre os nós do código LDPC. Além disso, quanto maior a dimensão da matriz identidade

que vai gerar os códigos IE-LDPC, mais o desempenho do algoritmo SM se aproxima do desempenho

do algoritmo log-SP.

4.1.2 Resultados da comparação do desempenho dos algoritmos log-SP e SM para os códigos

IE-LDPC (4000, 2000)

Cinco códigos foram construídos utilizando matriz identidade com os seguintes valores de

Page 64: Um estudo sobre a construção, desempenho e …

64

ordem: 50, 100, 200, 500 e 1000. As Figuras 4.6 a 4.10 mostram o desempenho dos algoritmos de

decodificação para estes códigos IE-LDPC (4000 2000).

4.1.2.1 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 50

A forma reduzida da matriz H código IE-LDPC (4000, 2000), gerada a partir de uma matriz

identidade de ordem igual a 50, do está representada na equação (4.5).

� = � �u) 2u) … 2u) Eu),< Eu),x … Eu),<x2u) �u) … 2u) Eu),<� Eu),xr … Eu),�⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2u) 2u) … �u) Eu),<r Eu),<y … Eu),t��

(4.5)

A Figura 4.6 mostra que para o presente código, o desempenho do algoritmo log-SP é melhor

que o do SM em torno de 1 dB, para BER aproximadamente igual a 10-3.

Figura 4.6 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz identidade

de ordem igual a 50.

4.1.2.2 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 100

Page 65: Um estudo sobre a construção, desempenho e …

65

A forma reduzida da matriz H do código IE-LDPC (4000, 2000), gerada a partir de uma matriz

identidade de ordem igual a 100, está representada na equação (4.6).

� = � �r)) 2r)) … 2r)) Er)),< Er)),x … Er)),yr2r)) �r)) … 2r)) Er)),yx Er)),y� … Er)),yx⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2r)) 2r)) … �r)) Er)),<r Er)),xx … Er)),tr�

(4.6)

Conforme ilustrado na Figura 4.7, para este código, a diferença de desempenho entre os dois

algoritmos chega a alcançar 1,3 dB a favor do log-SP, para BER igual a 10-4.

Figura 4.7 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz identidade

de ordem igual a 100.

4.1.2.3 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 200

A forma reduzida da matriz H do código IE-LDPC (4000, 2000), gerada a partir de uma matriz

identidade de ordem igual a 200, está representada na equação (4.7).

Page 66: Um estudo sobre a construção, desempenho e …

66

� = � �<)) 2<)) … 2<)) E<)),< E<)),x … E<)),<�2<)) �<)) … 2<)) E<)),xr E<)),xy … E<)),yr⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2<)) 2<)) … �<)) E<)),wy E<)),y� … E<)),rtr�

(4.7)

A Figura 4.8 mostra que, para este código, a diferença de desempenho a favor do algoritmo log-

SP fica em um intervalo que não excede o valor 0,75 dB.

Figura 4.8 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz identidade

de ordem igual a 200.

4.1.2.4 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 500

A forma reduzida da matriz H do código IE-LDPC (4000, 2000), gerada a partir de uma matriz

identidade de ordem igual a 500, está representada na equação (4.8).

� = � �u)) 2u)) … 2u)) Eu)),< Eu)),x … Eu)),rr2u)) �u)) … 2u)) Eu)),rx Eu)),ry … Eu)),<�⋮ ⋮ ⋱ ⋮ ⋮ ⋮ ⋱ ⋮2u)) 2u)) … �u)) Eu)),yx Eu)),y� … Eu)),�y�

(4.8)

A Figura 4.9 mostra que, para este código, o decréscimo de desempenho do algoritmo SM em

relação ao log-SP não ultrapassa 0,15 dB.

Page 67: Um estudo sobre a construção, desempenho e …

67

Figura 4.9 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz identidade

de ordem igual a 500.

4.1.2.5 Resultados para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 1000

A forma reduzida da matriz H do código IE-LDPC (4000, 2000), gerada a partir de uma matriz

identidade de ordem igual a 1000, está representada na equação (4.9).

� = � �r))) 2r)))2r))) �r))) Er))),< Er))),xEr))),u Er))),y� (4.9)

A Figura 4.10 mostra que, para este código, os dois algoritmos têm desempenho praticamente

idênticos, exceto por uma pequena diferença de 0,06 dB, em favor do algoritmo log-SP, para uma BER

próxima a 10-2.

Page 68: Um estudo sobre a construção, desempenho e …

68

Figura 4.10 - Curvas de desempenho para o código IE-LDPC (4000, 2000) gerado a partir de uma matriz

identidade de ordem igual a 1000.

Diferentemente do esperado, o código IE-LDPC(4000,2000) de melhor desempenho não o

código foi o código gerado a partir de uma matriz identidade de ordem igual a 50, e sim o código

gerado a partir de uma matriz identidade de ordem igual a 100, apesar do primeiro ter um número

maior de 1s por linha e coluna. Isso ocorre devido à existência de girth igual a 4 na matriz verificadora

de paridade do código IE-LDPC(4000,2000) gerado a partir de uma matriz identidade de ordem igual a

50. Como existem apenas 15 números primos menores que 50 e vinte matrizes circulantes são geradas

para gerar a matriz H, haverá 5 matrizes coincidentes a cada conjunto de 50 linhas. Novamente foi

observado para estes códigos que quanto maior a dimensão da matriz identidade que vai gerar os

códigos IE-LDPC, mais o desempenho do algoritmo SM se aproxima do desempenho do algoritmo log-

SP.

4.2 Resultados da síntese em FPGA do codificador e do decodificador LDPC

Esta seção apresenta os resultados da síntese do codificador e do decodificador para dois

Page 69: Um estudo sobre a construção, desempenho e …

69

códigos IE-LDPC na Virtex-5 XC5VLX50T, FPGA utilizada na presente dissertação.

Os codificadores e os decodificadores foram sintetizados em FPGA utilizando-se o software ISE

WebPACK da Xilinx. As implementações em VHDL do codificador e do decodificador foram simuladas

utilizando-se o software Modelsim. Os resultados obtidos através deste software foram comparados

com os resultados obtidos através da implementação do codificador e decodificador em MATLAB, a

fim de validar o funcionamento do codificador e do decodificador descritos em VHDL.

A ideia inicial era sintetizar os códigos IE-LDPC (2000, 1000) e IE-LDPC (4000, 2000) que

apresentassem decodificação SM com menor perda de desempenho em relação a log-SP. Porém, devido

às limitações físicas da plataforma FPGA utilizada, como alternativa foi realizada a síntese do

codificador e do decodificador para o código IE-LDPC (40, 20), gerado a partir de uma matriz

identidade de ordem igual a 10, e o código IE-LDPC (200, 100), gerado também a partir de uma matriz

identidade de ordem igual a 10. Em ambos os casos, o decodificador sintetizado executa apenas uma

iteração.

As tabelas 4.1 e 4.2 apresentam os resultados, em termos de parâmetros de implementação na

placa FPGA, das sínteses do codificador e do decodificador dos códigos IE-LDPC (40, 20) e IE-LDPC

(200, 100), respectivamente.

Tabela 4.1- Parâmetros do codificador e do decodificador do código IE-LDPC (40, 20) na FGPA

LDPC (40, 20)

Codificador Decodificador

n° de LUTs 47 4795 % de LUTs utilizadas 0,1 % 10,4 % n° de flip-flops 25 882 % de flip-flops utilizados 0,08 % 3 % Frequência máxima de operação

362,8 MHz 140,6 MHz

Tabela 4.2 - Parâmetros do codificador e do decodificador do código IE-LDPC (200, 100) na FGPA

LDPC (200, 100)

Codificador Decodificador

n° de LUTs 199 153264 % de LUTs utilizadas 0,4 % 332 %

Page 70: Um estudo sobre a construção, desempenho e …

70

n° de flip-flops 100 9962 % de flip-flops utilizados 0,3 % 34,6 % Frequência máxima de operação

330,8 MHz 46,8 MHz

Pela análise das tabelas 4.1 e 4.2, percebe-se que o decodificador do código IE-LDPC utiliza

bem mais LUTs e flip-flops do que o codificador, portanto, qualquer esforço em diminuir o número de

elementos da FPGA utilizados na implementação descrita nesta dissertação tem que ser concentrado no

decodificador.

O número de LUTs e flip-flops utilizados pelo decodificador aumenta consideravelmente com o

aumento do comprimento do código LDPC. A síntese do decodificador do código IE-LDPC (200, 100)

utilizou 11 vezes mais flip-flops e 32 vezes mais LUTs do que a síntese do código IE-LDPC (40, 20),

de comprimento cinco vezes menor.

Além disso, o decodificador do código IE-LDPC (200, 100) tem uma frequência máxima de

operação bem menor do que a do decodificador IE-LDPC (40, 20), levando à conclusão que para

códigos LDPC de comprimentos maiores, a frequência máxima do decodificador seria menor ainda.

O decodificador do código IE-LDPC (200, 100) utiliza mais LUTs do que as existentes na

FPGA utilizada, que possui um total de 28.800 flip-flops e 46.080 LUTs. O uso de uma FPGA com

mais LUTs e flip-flops influenciaria consideravelmente no preço comercial de um ipcore formado por

um codificador e decodificador LDPC. Por isto, a melhor alternativa para a síntese do decodificador

LDPC é o estudo de uma nova arquitetura e não a substituição da FPGA empregada no projeto.

O elevado número de LUTs utilizadas no decodificador está relacionado com a implementação

em VHDL, que armazenou os valores de �(&��) e �('��) em LUTs. Uma forma de diminuir a

quantidade de LUTs utilizadas pelo decodificador é o uso de uma memória cujos processos de escrita e

leitura funcionassem a uma taxa bem maior que o a taxa da propagação das mensagens �(&��) e �('��)

dentro do decodificador. Outra forma de diminuir a quantidade de LUTs utilizadas pelo decodificador é

representar os valores utilizados no cálculo da decodificação LDPC através de uma menor quantidade

de bits, em vez dos 12 bits atuais.

O número de LUTs e flip-flops mostrados nas tabelas 4.1 e 4.2 são apenas para uma iteração no

processo de decodificação. A cada nova iteração de decodificação, a quantidade total de elementos

lógicos e flip-flops do decodificador também teria que ser aumentada.

Page 71: Um estudo sobre a construção, desempenho e …

71

5 CONCLUSÃO E TRABALHOS FUTUROS

5.1 Conclusão

O desenvolvimento de códigos LDPC binários, irregulares e estruturados utilizando-se o

método descrito mostrou ser capaz de gerar códigos de forma simples e rápida. Como esperado, para

todos os códigos construídos, a decodificação utilizando o algoritmo soma-produto com razões

logarítmicas (log-SP) teve melhor desempenho do aquela em que foi utilizado o algoritmo soma-

mínimo (SM).

Para alguns códigos IE-LDPC, a diferença de desempenho entre os algoritmos de decodificação

ficou menor do que 0,2 dB, valor pequeno frente à economia de elementos lógicos que o algoritmo SM

propicia quando implementado. Vale ressaltar que quanto maior a dimensão da matriz identidade que

vai gerar os códigos IE-LDPC, mais o desempenho do algoritmo SM se aproxima do desempenho do

algoritmo log-SP.

Quanto à implementação em VHDL, a metodologia aplicada na decodificação precisa ser

melhor dimensionada para sua sintetização em FPGA, tendo em vista que esta utilizou muitos

elementos lógicos.

A utilização de mais placas FPGA de modo a dividir as operações executadas no processo de

decodificação também seria uma possibilidade de implementação. Esta alternativa seria a mais viável

embora envolva um maior custo financeiro de implementação.

Os códigos IE-LDPC obtidos e analisados mostram que, ajustando-se a dimensão da matriz

identidade geradora das submatrizes circulantes componentes da matriz H, pode-se fazer com que o

desempenho do algoritmo de decodificação SM se aproxime do desempenho do algoritmo log-SP,

propiciando uma considerável redução de elementos lógicos na placa FPGA sem que haja uma

degradação significativa do desempenho em termos de BER por Eb/N0.

5.2 Trabalhos Futuros

Para o desenvolvimento e implementação de um código LDPC de bom desempenho com

Page 72: Um estudo sobre a construção, desempenho e …

72

aplicação em comunicações ópticas, os seguintes trabalhos ainda necessitam ser realizados:

a) Estudo, construção e análise do desempenho de outros códigos estruturados tais como os

códigos LDPC quase-cíclicos (QC-LDPC);

b) Estudo de códigos estruturados não-binários;

c) Estudo de outros algoritmos sub-ótimos de decodificação de códigos LDPC;

d) Implementação de arquiteturas do decodificador LDPC que utilizem menor quantidade de

elementos lógicos na placa FPGA;

e) Modelagem mais precisa do canal óptico;

f) Representação com menor número de bits da notação em ponto fixo dos números envolvi-

dos no cálculo da decodificação dos códigos LDPC;

g) Estudo e implementação de código corretores de erro conjuntamente com modulação não

binária (BPSK);

h) Desenvolvimento da interface óptica-elétrica necessária para a validação em hardware do

codificador e do decodificador LDPC sintetizados em FPGA.

Page 73: Um estudo sobre a construção, desempenho e …

73

REFERÊNCIAS BIBLIOGRÁFICAS

[1] I. Djordjevic, W. Ryan and B. Vasic, Coding for optical channels. New York: Springer, 2010.

[2] Wada, H., et al. FEC Considerations for 10Gbps EPON System. September 18, 2006. Disponível em: <http://www.ieee802.org/3/av/public/2006_09/3av_0609_wada_1.pdf> Acesso em: 17 ago.2010.

[3] J. Castiñeira Moreira and P. Farrell, Essentials of error-control coding. West Sussex, England: John Wiley & Sons, 2006.

[4] Sae-Young Chung; Forney, G.D., Jr.; Richardson, T.J.; Urbanke, R., "On the design of low-density parity-check codes within 0.0045 dB of the Shannon limit," in Communications Letters, IEEE , vol.5, no.2, pp.58-60, Feb 2001.

[5] IEEE Unapproved Draft Std P802.11n/D11.0, Jun. 2009.

[6] M. Jobes. A VLSI Architecture and the FPGA Implementation for multi-rate LDPC Decoding, MASc thesis, McMaster University, 2009.

[7] M. Karkooti. Semi-Parallel Architectures for Real-Time LDPC Coding, MASc thesis, Rice University, 2004.

[8] W. E. Ryan. An Introduction to LDPC codes. Disponível em: <http://www.telecom.tuc.gr/~alex/papers/ryan.pdf> Acesso em: 13 fev.2011.

[9] J. Teubner and L. Woods, Data processing on FPGAs. San Rafael, Calif.: Morgan & Claypool, 2013.

[10] Virtex-5 FPGA User Guide. Disponível em: <http://www.xilinx.com/support/documentation/user_guides/ug190.pdf> Acesso em: 22 jun. de 2012.

[11] Karkooti, M.; Cavallaro, J.R., "Semi-parallel reconfigurable architectures for real-time LDPC decoding," Information Technology: Coding and Computing, 2004. Proceedings. ITCC 2004. International Conference on , vol.1, no., pp.579,585 Vol.1, 5-7 April 2004.

[12] Mansour, M.M.; Shanbhag, N.R., "Low-power VLSI decoder architectures for LDPC codes," in Low Power Electronics and Design, 2002. ISLPED '02. Proceedings of the 2002 International Symposium on, vol., no., pp.284-289, 2002.

[13] L. Yang. An area-efficient architecture for the implementation of LDPC decoder, MASc thesis, Case Western Reserve University, 2011.

[14] Xiao-Yu Hu; Eleftheriou, E.; Arnold, D.-M.; Dholakia, A., "Efficient implementations of the sum-product algorithm for decoding LDPC codes," in Global Telecommunications Conference, 2001. GLOBECOM '01. IEEE , vol.2, no., pp.1036-1036E vol.2, 2001.

[15] Hosseini, S.M.E.; Sann Chan, Kheong; Wang Ling Goh, "A reconfigurable FPGA implementation

Page 74: Um estudo sobre a construção, desempenho e …

74

of an LDPC decoder for unstructured codes," in Signals, Circuits and Systems, 2008. SCS 2008. 2nd International Conference on , vol., no., pp.1-6, 7-9 Nov. 2008.

[16] Darabiha, A.; Carusone, A.C.; Kschischang, F.R., "A bit-serial approximate min-sum LDPC decoder and FPGA implementation," in Circuits and Systems, 2006. ISCAS 2006. Proceedings. 2006 IEEE International Symposium on , vol., no., pp.4 pp.-, 21-24 May 2006.

[17] Kamiya, N.; Shioiri, S., "Concatenated QC-LDPC and SPC codes for 100 Gbps ultra long-haul optical transmission systems," in Optical Fiber Communication (OFC), collocated National Fiber Optic Engineers Conference, 2010 Conference on (OFC/NFOEC), vol., no., pp.1-3, 21-25 March 2010.

[18] Djordjevic, I.B.; Arabaci, M.; Minkov, L.L., "Next Generation FEC for High-Capacity Communication in Optical Transport Networks," in Lightwave Technology, Journal of, vol.27, no.16, pp.3518-3530, Aug.15, 2009.

[19] Yun Chen; Xiang Chen; Yifei Zhao; Chunhui Zhou; Jing Wang, "Design and implementation of multi-mode QC-LDPC decoder," in Communication Technology (ICCT), 2010 12th IEEE International Conference on, vol., no., pp.1145-1148, 11-14 Nov. 2010.

[20] Spagnol, C.; Marnane, W., "A class of quasi-cyclic LDPC codes over GF(2m)," in Communications, IEEE Transactions on, vol.57, no.9, pp.2524-2527, September 2009.

[21] Chung-Jin Tsai; Mu-Chung Chen, "Efficient LDPC decoder implementation for DVB-S2 system," in VLSI Design Automation and Test (VLSI-DAT), 2010 International Symposium on, vol., no., pp.37-40, 26-29 April 2010.

[22] Zhengya Zhang; Dolecek, L.; Lee, P.; Anantharam, V.; Wainwright, M.J.; Richards, B.; Nikolic, B., "Low error rate LDPC decoders," in Signals, Systems and Computers, 2009 Conference Record of the Forty-Third Asilomar Conference on , vol., no., pp.1278-1282, 1-4 Nov. 2009.

[23] Jie Jin; Chi-ying Tsui, "A low power layered decoding architecture for LDPC decoder implementation for IEEE 802.11n LDPC codes," in Low Power Electronics and Design (ISLPED), 2008 ACM/IEEE International Symposium on , vol., no., pp.253-258, 11-13 Aug. 2008.

[24] Fanucci, L.; Rossi, F., "A throughput/complexity analysis for the VLSI implementation of LDPC decoder," in Signal Processing and Information Technology, 2004. Proceedings of the Fourth IEEE International Symposium on , vol., no., pp.409-412, 18-21 Dec. 2004.

[25] Hong Ding; Shuai Yang; Wu Luo; Mingke Dong, "Design and Implementation for High Speed LDPC Decoder with Layered Decoding," in Communications and Mobile Computing, 2009. CMC '09. WRI International Conference on , vol.1, no., pp.156-160, 6-8 Jan. 2009.

[26] Guilloud, F.; Boutillon, E.; Tousch, J.; Danger, J.-L., "Generic Description and Synthesis of LDPC Decoders," in Communications, IEEE Transactions on , vol.55, no.11, pp.2084-2091, Nov. 2007.

[27] Bhatt, T., Narayanan, K., & Kehtarnavaz, N. (2000, October). Fixed point DSP implementation of low-density parity check codes. In Proc. Ninth DSP Workshop, Hunt, Texas.

Page 75: Um estudo sobre a construção, desempenho e …

75

[28] Brack, T.; Alles, M.; Lehnigk-Emden, T.; Kienle, F.; Wehn, N.; L'Insalata, N.E.; Rossi, F.; Rovini, M.; Fanucci, L., "Low Complexity LDPC Code Decoders for Next Generation Standards," in Design, Automation & Test in Europe Conference & Exhibition, 2007. DATE '07 , vol., no., pp.1-6, 16-20 April 2007.

[29] Beuschel, C.; Pfleiderer, Hans-Jörg, "FPGA implementation of a flexible decoder for long LDPC codes," in Field Programmable Logic and Applications, 2008. FPL 2008. International Conference on , vol., no., pp.185-190, 8-10 Sept. 2008.

[30] Mizuochi, T.; Konishi, Y.; Miyata, Y.; Inoue, T.; Onohara, K.; Kametani, S.; Sugihara, T.; Kubo, K.; Kobayashi, T.; Yoshida, H.; Ichikawa, T., "FPGA based prototyping of next generation forward error correction," in Optical Communication, 2009. ECOC '09. 35th European Conference on , vol., no., pp.1-4, 20-24 Sept. 2009.

[31] Yongyi Mao; Banihashemi, A.H., "A heuristic search for good low-density parity-check codes at short block lengths," in Communications, 2001. ICC 2001. IEEE International Conference on, vol.1, no., pp.41-44 vol.1, 11-14 Jun 2001.

[32] Sae-Young Chung; Richardson, T.J.; Urbanke, R.L., "Analysis of sum-product decoding of low-density parity-check codes using a Gaussian approximation," in Information Theory, IEEE Transactions on , vol.47, no.2, pp.657-670, Feb 2001.

[33] W. P. de S. Guimarães, Decodificação híbrida para códigos LDPC, Tese (Doutorado em Eng. Elétrica), Programa de Pós-Graduação em Engenharia Elétrica da Universidade Federal de Pernambuco, Recife, PE, 2013.

[34] M. A. C. Gomes, Códigos binários definidos por matrizes de teste de paridade esparsas algoritmos de descodificação, MASc thesis,Universidade de Coimbra, 2003.

[35] LDPC code using MATLAB and C MEX. Disponível em <http://sites.google.com/site/bsnugroho/ldpc>. Acesso em: 3 set. 2011.

[36] Soares, André. “Desafios das próximas gerações de Redes Ópticas de Transporte.” UFPI. ENUCOMP 2013. Disponível em <http://www.enucomp.com.br/2013/conteudos/palestras/palestra_andre.pdf>. Acesso em: 27 jul. 2014.

Page 76: Um estudo sobre a construção, desempenho e …

76

ANEXOS

Page 77: Um estudo sobre a construção, desempenho e …

77

ANEXO A – Código-fonte dos arquivos desenvolvidos para realizar a análise do desempenho dos

algoritmos log-SP e SM utilizando os códigos IE-LDPC construídos

% ----------------------------------------------------------------------------

%% ldpd_top.m %%

% Script to test dec_logSP_f.

clear;

clc;

tic;

%% File for the results

fid = fopen('ber_res.txt','w');

%% Signal-to-noise ratio

SNR_dB = 0:.5:7;

%SNR_dB = 2;

%% Initializations

% error number for log-SP algorithm

n1_err = zeros(1,length(SNR_dB));

% error number for SM algorithm

n2_err = zeros(1,length(SNR_dB));

% number of transmitted words

%N = 10^4;

%N = 10^3

N_vec = [10^3 10^3 10^3 10^3 10^3 10^4 10^4 10^4 10^5 10^5 10^5 10^6 10^6 10^7 10^7];

n_min_err = [100 100 100 50 50 50 25 25 25 25 10 10 10 10 10];

%% generating parity-check and generator matrix

n = 2000;

k = 1000;

dim = 500; % identity matrix dimension

[H, G] = gen_mat_f(n,k,dim);

%% Iteration loop

Page 78: Um estudo sobre a construção, desempenho e …

78

% number of errors

n1_err = zeros(1,length(SNR_dB));

n2_err = zeros(1,length(SNR_dB));

% number of iterations

niter1 = zeros(1,length(SNR_dB));

niter2 = zeros(1,length(SNR_dB));

for ii = 1:length(SNR_dB)

err1 = 0;

err2 = 0;

for ll = 1:N_vec(ii)

%% Monte Carlo loop

if ((n1_err(ii) < n_min_err(ii)) && (n2_err(ii) < n_min_err(ii)))

%% LDPC encoding

m = randint(1,k,[0,1]);

c = ldpc_enc_f(m,G);

%% Modulation

x = 1 - 2*c;

%% Transmitting over a AWGN channel

[y, sigma] = awgn_channel_f(x,SNR_dB(ii));

%y = x;

%% LDPC decoding

fprintf('Decoding %d word for %0.1f dB\n',ll,SNR_dB(ii));

% number of iterations

iter = 5;

% log-SP decoding

[logSP_c_hat, logSP_ok] = dec_logSP_f(y,H,iter,n,k,sigma);

%c

%logSP_c_hat

% SM decoding

[SM_c_hat, SM_ok] = dec_SM_f(y,H,iter,n,k);

%c

%SM_c_hat

%% Error computation

err1 = err1 + biterr(c,logSP_c_hat);

err2 = err2 + biterr(c,SM_c_hat);

niter1 = ll;

niter2 = ll;

Page 79: Um estudo sobre a construção, desempenho e …

79

n1_err(ii) = err1;

n2_err(ii) = err2;

n1_iter(ii) = niter1;

n2_iter(ii) = niter2;

% BER

ber1(ii) = n1_err(ii)/(n1_iter(ii)*length(y));

%ber1(ii) = n1_err(ii)/(N*length(y));

ber2(ii) = n2_err(ii)/(n2_iter(ii)*length(y));

%ber2(ii) = n1_err(ii)/(N*length(y));

fprintf('ber1: %d ber2: %d \n',n1_err(ii),n2_err(ii));

fprintf(fid,'ber1: %d ber2: %d \n',n1_err(ii),n2_err(ii));

else

break;

end

end

end

%% BER plot

figure('Color',[1 1 1]); % change background color

set(gca, 'Fontsize', 16)

semilogy(SNR_dB, ber1, 'rd-.', 'Linewidth', 3, 'Markersize', 8);

hold all;

semilogy(SNR_dB, ber2, 'bo-.', 'Linewidth', 3, 'Markersize', 8);

hold all;

xlabel('Eb/N0(dB)');

ylabel('BER');

grid on

legend('log-SP','SM',1);

%grid on;

hold off;

n1_err

n2_err

n1_iter

n2_iter

ber1

ber2

%% File

fclose(fid);

toc;

% ----------------------------------------------------------------------------

Page 80: Um estudo sobre a construção, desempenho e …

80

%% gen_mat_f.m %%

% This function generates a matrix H based on its colunm number (n), its

% line number (k) and the dimension of its basic matrix (dim).

function [H, G] = gen_mat_f(n,k,dim)

% There will be used ((n-k)/dim)*(k/dim) rotated matrices.

% The matrices are a prime number shifted.

% Initializing the matrix.

% Pt = transpose matrix of parity matrix

Pt = zeros((n-k),k);

% Prime number set. The value 20000 was chosen because for LDPC(4000,2000)

% and dim = 50, it is necessary 1600 shift values.

Prime_set = primes(200000);

% index of the prime number set element

index = 1;

% x1 is the column index inside matrix Mat

% x2 is the line index inside matrix Mat

for i=1:(n-k)/dim

for j=1:k/dim

% shift number

nrot = Prime_set(index);

% shifted matrix

Mrot = rot_mat_f(dim,nrot);

x1 = dim*(j-1)+ 1;

x2 = dim*(i-1)+ 1;

Pt(x2:x2+dim-1,x1:x1+dim-1) = Mrot;

index = index + 1;

end

end

% parity-check matrix

H = [eye(n-k) Pt];

% parity matrix

P = Pt';

% generator matrix

G = [P eye(k)];

Page 81: Um estudo sobre a construção, desempenho e …

81

% ----------------------------------------------------------------------------

%% rot_mat_f.m %%

% This function generates a matrix from the identity matrix shifted nrot

% colunms to the right.

% dim = identity matrix dimension

% nrot = right shift number

function Mrot = rot_mat_f(dim,nrot)

Meye = eye(dim);

P = [Meye(:,dim) Meye(:,1:dim-1)];

% initialized with the identity matrix

Mrot = P;

if nrot == 0

Mrot = eye(dim);

else

if nrot == 1

Mrot = P;

else

for i=1:mod(nrot-1,dim)

Mrot = Mrot*P;

end

end

end

% ----------------------------------------------------------------------------

%% ldpc_enc_f.m %%

% LDPC encoder

% m : word to be encoded

% G : generator matrix

function c = ldpc_enc_f(m,G)

% G = k x n

% m = 1 x k

% It is necessary to use m' at the multiplication

% Multiplication done at GF(2)

gf_m = gf(m',2);

gf_G = gf(G',2);

Page 82: Um estudo sobre a construção, desempenho e …

82

% G' = n x k m' = k x 1

% Multiplication G' and m' --> n x 1

gf_c = gf_G*gf_m;

% encoded word

c(gf_c == 1) = 1;

c(gf_c == 0) = 0;

% ----------------------------------------------------------------------------

%% awgn_channel_f.m %%

% AWGN channel

function [y, sigma] = awgn_channel_f(x,SNR)

N0 = 10^-(0.1*SNR);

sigma = sqrt(N0/2);

noise = sigma*randn(1,length(x));

y = x + noise;

% ----------------------------------------------------------------------------

%% dec_logSP_f.m %%

% Implementation of LDPC decoding algorithm log-SP.

% y: received word

% H: parity-check matrix

% iter: iteration number

function [c_hat, ok] = dec_logSP_f(y,H,iter,n,k,sigma)

% number of iterations done by the loop

it = 0;

ok = 1;

while (ok ~= 0 && it < iter)

if (it == 0)

% finding Hzon

[Hzon, wc_vec, wc] = hzon_f(H,n);

%Hzon

Page 83: Um estudo sobre a construção, desempenho e …

83

% finding Hver

[Hver, wr_vec, wr] = hver_f(H,k);

%Hver

% initialization

[Lc, Lq] = logSP_init_f(y,sigma,n,wc);

end

% Horizontal step

Lr = logSP_Hstep_f(Lq,Hzon,Hver,k,wr,wr_vec,wc_vec);

% Vertical step

Lq = Vstep_f(Lr,Lc,Hzon,Hver,n,wc,wc_vec,wr_vec);

% Q calculation

Q = Qcalc_f(Lr,Lc,Hzon,Hver,n,wc_vec,wr_vec);

% Decision

c_hat = decision_f(Q,n);

% Syndrome

synd = synd_f(c_hat, H);

ok = sum(synd.x);

it = it + 1;

end

% ----------------------------------------------------------------------------

%% hzon_f.m %%

% The matrix Hzon stores the columns of the matrix H where there are

% non-zero elements.

function [Hzon, wc_vec, wc] = hzon_f(H,n)

% column and line positions for H(1,1) == 1

[row, col] = find(H == 1);

% vector with wc for all columns

wc_vec = zeros(1,n);

% determining wc

max_wc = 0;

Page 84: Um estudo sobre a construção, desempenho e …

84

for i=1:n

% number of 1s in a column

n_wc = 0;

for j=1:length(col)

if col(j) == i

n_wc = n_wc + 1;

end

end

wc_vec(i) = n_wc;

if n_wc >= max_wc

max_wc = n_wc;

end

end

wc = max_wc;

% initializing Hzon

Hzon = zeros(wc,n);

for i=1:n

% row inside Hzon

jrow = 0;

for j=1:size(col)

if col(j) == i

jrow = jrow + 1;

Hzon(jrow,i)= row(j);

end

end

end

% ----------------------------------------------------------------------------

%% hver_f.m %%

% The matrix Hver stores the lines of the matrix H where there are non-zero

% elements.

function [Hver, wr_vec, wr] = hver_f(H,k)

% Finding line and column positions for H(i,j) == 1

[row, col] = find(H == 1);

% vector with wr for all rows

wr_vec = zeros(1,k);

% determining wr

max_wr = 0;

Page 85: Um estudo sobre a construção, desempenho e …

85

for j=1:k

% number of 1s in a line

n_wr = 0;

for i=1:length(row)

if row(i) == j

n_wr = n_wr + 1;

end

end

wr_vec(j) = n_wr;

if n_wr >= max_wr

max_wr = n_wr;

end

end

wr = max_wr;

% initializing Hver

Hver = zeros(k,wr);

for j=1:k

% row inside Hzon

icol = 0;

for i=1:length(row)

if row(i) == j

icol = icol + 1;

Hver(j,icol)= col(i);

end

end

end

% ----------------------------------------------------------------------------

%% logSP_init_f.m %%

% log-SP algorithm initialization of Lc and Lq vectors.

function [Lc, Lq] = logSP_init_f(y,sigma,n,wc)

Lc = zeros(1,n);

Lq = zeros(wc,n);

for i=1:n

Lc(i) = (2*y(i))/(sigma^2);

for j=1:wc

Lq(j,i) = Lc(i);

Page 86: Um estudo sobre a construção, desempenho e …

86

end

end

% ----------------------------------------------------------------------------

%% logSP_Hstep_f.m %%

% Function to calculate horizontal step for log-SP algorithm.

function Lr = logSP_Hstep_f(Lq,Hzon,Hver,k,wr,wr_vec,wc_vec)

Lr = zeros(k,wr);

% line loop

for j=1:k

% column loop

for i=1:wr_vec(j)

alfa = 1;

sum_beta = 0;

% elements in the line loop

for l =1:wr_vec(j)

if(l ~= i)

col_Lq = Hver(j,l);

% loop inside Hzon column

for ll=1:wc_vec(col_Lq)

if (Hzon(ll,col_Lq) == j)

line_Lq = ll;

end

end

alfa = alfa*sign(Lq(line_Lq,col_Lq));

beta = abs(Lq(line_Lq,col_Lq));

sum_beta = sum_beta + alfa_f(beta);

end

end

Lr(j,i) = alfa*alfa_f(sum_beta);

end

end

% ----------------------------------------------------------------------------

%% Vstep_f.m %%

% Function that performs Vertical Step of LDPC decodification

function Lq = Vstep_f(Lr,Lc,Hzon,Hver,n,wc,wc_vec,wr_vec)

Lq = zeros(wc,n);

Page 87: Um estudo sobre a construção, desempenho e …

87

% column loop

for i=1:n

% line loop

for j=1:wc_vec(i)

sum_Lr = 0;

% elements in the column loop

for l=1:wc_vec(i)

if (j~=l)

line_Lr = Hzon(l,i);

for ll=1:wr_vec(line_Lr)

if (Hver(line_Lr,ll) == i)

col_Lr = ll;

end

end

sum_Lr = sum_Lr + Lr(line_Lr,col_Lr);

end

end

Lq(j,i) = Lc(i) + sum_Lr;

end

end

% ----------------------------------------------------------------------------

%% Qcalc_f.m %%

% Function that performs Vertical Step of LDPC decodification

function Q = Qcalc_f(Lr,Lc,Hzon,Hver,n,wc_vec,wr_vec)

Q = zeros(1,n);

for i=1:n

sum_Q = 0;

for j=1:wc_vec(i)

% elements in the column loop

line_Lr = Hzon(j,i);

for ll=1:wr_vec(line_Lr)

if (Hver(line_Lr,ll) == i)

col_Lr = ll;

end

end

sum_Q = sum_Q + Lr(line_Lr,col_Lr);

end

Q(i) = Lc(i) + sum_Q;

end

Page 88: Um estudo sobre a construção, desempenho e …

88

% ----------------------------------------------------------------------------

%% decision_f.m %%

% Function to calculate the decoded word.

function c_hat = decision_f(Q,n)

% decoded word

c_hat = zeros(1,n);

c_hat(Q < 0) = 1;

c_hat(Q >= 0) = 0;

% ----------------------------------------------------------------------------

%% synd_f.m %%

% Function that calculates the syndrome of the decoded word.

function synd = synd_f(c_hat, H)

% Transforming c_hat to GF(2) to perform matrix multiplication

gf_c_hat = gf(c_hat',2);

synd = H*gf_c_hat;

% ----------------------------------------------------------------------------

%% dec_SM_f.m %%

% Implementation of LDPC decoding algorithm log-SP.

% y: received word

% H: parity-check matrix

% iter: iteration number

function [c_hat, ok] = dec_SM_f(y,H,iter,n,k)

% number of iterations done by the loop

it = 0;

ok = 1;

while (ok ~= 0 && it < iter)

if (it == 0)

% finding Hzon

Page 89: Um estudo sobre a construção, desempenho e …

89

[Hzon, wc_vec, wc] = hzon_f(H,n);

%Hzon

% finding Hver

[Hver, wr_vec, wr] = hver_f(H,k);

%Hver

% initialization

[Lc, Lq] = SM_init_f(y,n,wc);

end

% Horizontal step

Lr = SM_Hstep_f(Lq,Hzon,Hver,k,wr,wr_vec,wc_vec);

% Vertical step

Lq = Vstep_f(Lr,Lc,Hzon,Hver,n,wc,wc_vec,wr_vec);

% Q calculation

Q = Qcalc_f(Lr,Lc,Hzon,Hver,n,wc_vec,wr_vec);

% Decision

c_hat = decision_f(Q,n);

% Syndrome

synd = synd_f(c_hat, H);

ok = sum(synd.x);

it = it + 1;

end

% ----------------------------------------------------------------------------

%% SM_init_f.m %%

% SM algorithm initialization of Lc and Lq vectors.

function [Lc, Lq] = SM_init_f(y,n,wc)

Lc = zeros(1,n);

Lq = zeros(wc,n);

for i=1:n

Lc(i) = y(i);

for j=1:wc

Page 90: Um estudo sobre a construção, desempenho e …

90

Lq(j,i) = Lc(i);

end

end

% ----------------------------------------------------------------------------

%% SM_Hstep_f.m %%

% Function to calculate horizontal step for log-SP algorithm.

function Lr = SM_Hstep_f(Lq,Hzon,Hver,k,wr,wr_vec,wc_vec)

Lr = zeros(k,wr);

% line loop

for j=1:k

% column loop

for i=1:wr_vec(j)

alfa = 1;

% first iteration

first = 0;

% elements in the line loop

for l=1:wr_vec(j)

if(i~=l)

col_Lq = Hver(j,l);

% loop inside Hzon clolumn

for ll=1:wc_vec(col_Lq)

if (Hzon(ll,col_Lq) == j)

line_Lq = ll;

end

end

alfa = alfa * sign(Lq(line_Lq,col_Lq));

beta = abs(Lq(line_Lq,col_Lq));

if first == 0

mim_beta = beta;

else

if beta < mim_beta

mim_beta = beta;

end

end

first = 1;

end

end

Lr(j,i)= alfa*mim_beta;

end

end

% ----------------------------------------------------------------------------

Page 91: Um estudo sobre a construção, desempenho e …

91

ANEXO B - Código-fonte dos arquivos desenvolvidos para a implementação em VHDL do

codificador e do decodificador dos códigos IE-LDPC construídos

# ----------------------------------------------------------------------------

-- Package that store the functions that performs sum and gives the minimum

-- value of two numbers.

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;

use ieee.numeric_std.all;

package rasc_pkg is

-- NOTE: I use to instead of downto for Lq_t e Lr_t to facilitate validation

-- using MATLAB.

-- LDPC dimensions

constant n_c : integer := 8;

constant k_c : integer := 4;

-- number of bit per value

constant bit_c : integer := 12;

constant zero_c : std_logic_vector(bit_c-1 downto 0):= conv_std_logic_vector(0,bit_c);

-- Hzon

constant nrow_Hzon_c : integer := k_c;

constant ncol_Hzon_c : integer := 4;

-- Hver

constant nrow_Hver_c : integer := n_c;

constant ncol_Hver_c : integer := 2;

type row_t is array(n_c-1 downto 0) of std_logic_vector(bit_c-1 downto 0);

-- Lq

type row_Hzon_t is array(0 to ncol_Hzon_c-1) of std_logic_vector(bit_c-1 downto 0);

type Lq_t is array(0 to k_c-1) of row_Hzon_t;

-- Hzon

type Hzon_matrix_t is array(1 to nrow_Hzon_c, 1 to ncol_Hzon_c) of integer;

Page 92: Um estudo sobre a construção, desempenho e …

92

-- Hzon matrix

constant Hzon_c : Hzon_matrix_t := (

(1,3,6,7),

(2,5,6,8),

(2,3,4,5),

(1,4,7,8)

);

-- Lr

type row_Hver_t is array(0 to ncol_Hver_c-1) of std_logic_vector(bit_c-1 downto 0);

type Lr_t is array(0 to n_c-1) of row_Hver_t;

-- Hver

type Hver_matrix_t is array(1 to nrow_Hver_c, 1 to ncol_Hver_c) of integer;

-- Hver matrix

constant Hver_c : Hver_matrix_t := (

(1,4),

(2,3),

(1,3),

(3,4),

(2,3),

(1,2),

(1,4),

(2,4)

);

-- LDPC encoder

function ldpc_enc_f(data_i: std_logic_vector(k_c-1 downto 0))

return std_logic_vector;

-- sum of two numbers

function sum_f(a_v: std_logic_vector(bit_c-1 downto 0);

b_v: std_logic_vector(bit_c-1 downto 0))

return std_logic_vector;

-- minimum of two numbers

function min_f(a_v: std_logic_vector(bit_c-1 downto 0);

b_v: std_logic_vector(bit_c-1 downto 0))

return std_logic_vector;

-- LDPC decision

function decision_f(a_v: std_logic_vector(bit_c-1 downto 0))

return std_logic;

end rasc_pkg;

Page 93: Um estudo sobre a construção, desempenho e …

93

package body rasc_pkg is

-- LDPC encoder

function ldpc_enc_f(data_i: std_logic_vector(k_c-1 downto 0))

return std_logic_vector is

variable data_v : std_logic_vector(n_c-1 downto 0);

variable aux_v : std_logic := '0';

-- message

data_v(0 to k_c-1) = data_i(0 to k_c-1);

aux_v := 0;

for j in k_c to n_c-1 loop

data_v(j) := 0;

for i in 1 to ncol_Hver_c loop

if Hver_c(j,i) /= 1 then

data_v(j) := data_v(j) xor data_i(Hver_c(j,i)-1);

end if;

end loop;

end loop;

-- data_v : encoded data

return data_v;

end ldpc_enc_f;

-- sum function

function sum_f(a_v : std_logic_vector(bit_c-1 downto 0);

b_v: std_logic_vector(bit_c-1 downto 0))

return std_logic_vector is

-- The factors have size of 12 bits

-- It is necessary to truncate the number when the result is bigger

-- than 127 or littler than -128.

-- maximum value: 127

-- minimum value: - 128

-- Bitwise operation is performed

variable res_v: std_logic_vector(bit_c-1 downto 0);

variable carry_v: std_logic_vector(bit_c-1 downto 0);

Page 94: Um estudo sobre a construção, desempenho e …

94

variable result_v: std_logic_vector(bit_c-1 downto 0);

variable underflow_v : std_logic;

begin

res_v(0) := a_v(0) xor b_v(0);

carry_v(0) := a_v(0) and b_v(0);

for j in 1 to 11 loop

carry_v(j) := (a_v(j) and b_v(j)) or (a_v(j) and carry_v(j-1)) or (b_v(j) and carry_v(j-1));

res_v(j) := a_v(j) xor b_v(j) xor carry_v(j-1);

end loop;

-- I have to use the predecessors, so it is to instead of downto.

-- carry_v(11) will signalized if there is overflow or underflow.

-- overflow: both positive and carry(msb) = '1'

-- underflow: both negative and carry(msb) xor carry(msb-1) = '1'

underflow_v := carry_v(11) xor carry_v(10);

-- overflow detection

if a_v(11) = '0' and b_v(11) = '0' and carry_v(10) = '1' then

-- 127 Remember that the four lsb are the fractional part

result_v := conv_std_logic_vector(2032,12);

-- underflow detection

elsif (a_v(11) = '1' and b_v(11) = '1') and underflow_v = '1' then

-- -128 Remember that the four lsb are the fractional part

result_v := conv_std_logic_vector(2048,12);

else

result_v := res_v;

end if;

return result_v;

end sum_f;

-- minimum value function

function min_f(a_v: std_logic_vector(bit_c-1 downto 0);

b_v: std_logic_vector(bit_c-1 downto 0))

return std_logic_vector is

-- integer values

variable a_int_v : integer range 0 to 2047;

variable b_int_v : integer range 0 to 2047;

-- minimum value

variable min_value_v : std_logic_vector(bit_c-1 downto 0);

begin

Page 95: Um estudo sobre a construção, desempenho e …

95

-- both positive

if a_v(11) = '0' and b_v(11) = '0' then

a_int_v := conv_integer(a_v(10 downto 0));

b_int_v := conv_integer(b_v(10 downto 0));

if a_int_v > b_int_v then

min_value_v := b_v;

else

min_value_v := a_v;

end if;

-- a < 0 and b >= 0

elsif a_v(11) = '1' and b_v(11) = '0' then

min_value_v := a_v;

-- a >= 0 and b < 0

elsif a_v(11) = '0' and b_v(11) = '1' then

min_value_v := b_v;

-- both negative

else

a_int_v := conv_integer(a_v(10 downto 0));

b_int_v := conv_integer(b_v(10 downto 0));

if a_int_v < b_int_v then

min_value_v := a_v;

else

min_value_v := b_v;

end if;

end if;

return min_value_v;

end min_f;

-- LDPC decision

function decision_f(a_v: std_logic_vector(bit_c-1 downto 0))

return std_logic is

-- result

variable res_v : std_logic;

begin

-- If a_v is positive, res_v = '1', otherwise, res_v = '0'

if a_v(bit_c-1) = '0' then

res_v := '1';

else

res_v := '0';

end if;

return res_v;

Page 96: Um estudo sobre a construção, desempenho e …

96

end function decision_f;

end package body rasc_pkg;

# ----------------------------------------------------------------------------

library ieee;

use ieee.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.numeric_std.all;

library ldpc_lp;

use ldpc_lp.rasc_pkg.all;

-- Encoder for an LDPC binary code.

entity ldpc_encoder_top is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

data_i : in std_logic_vector(k_c-1 downto 0);

data_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_encoder_top;

-- The codeword is obtained by msg * H.

architecture rtl of ldpc_encoder_top is

begin

process(rst_i, mclk_i)

begin

if rst_i = '1' then

data_o <= (others => '0');

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

for j in n_c-1 downto 0 loop

data_o <= ldpc_enc_f(data_i);

end loop;

end if;

end if;

end process;

end rtl;

# ----------------------------------------------------------------------------

Page 97: Um estudo sobre a construção, desempenho e …

97

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This is the implementation of a ldpc decoder.

entity ldpc_decoder_top is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

new_word_i : in std_logic;

rx_i : in row_t;

-- output

dec_data_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_decoder_top;

-- new_word_i : flag to indicate a incoming data.

-- rx_i : ldpc word. It is a array of n_c elements of bit_c bits.

-- It stores corresponds to values in the [-1,1] interval.

-- dec_data_o : decoded ldpc word.

-- This code version implemented a three-iteratin LDPC decoder.

architecture rtl of ldpc_decoder_top is

-- first iteration

component ldpc_first_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

rx_i : in row_t;

new_word_i : in std_logic;

-- output

Page 98: Um estudo sobre a construção, desempenho e …

98

Lc_o : out row_t;

Lq_o : out Lq_t;

Lr_o : out Lr_t;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

-- output signals for the inner iteration block

signal Lc_first_s : row_t;

signal Lq_first_s : Lq_t;

signal Lr_first_s : Lr_t;

-- inner iterations

component ldpc_middle_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

new_word_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

-- output

Lr_o : out Lr_t;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

-- output for the last iteration block

signal Lc_inner_s : row_t;

signal Lq_inner_s : Lq_t;

signal Lr_inner_s : Lr_t;

-- last iteration

component ldpc_last_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

Page 99: Um estudo sobre a construção, desempenho e …

99

new_word_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

-- output

dec_data_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

begin

-- first iteration

ldpc_first_iter_block_inst: ldpc_first_iter_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => en_i,

rx_i => rx_i,

new_word_i => new_word_i,

Lc_o => Lc_first_s,

Lq_o => open,

Lr_o => Lr_first_s,

dec_rx_o => open

);

-- inner iterations

ldpc_middle_iter_block_inst: ldpc_middle_iter_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => en_i,

new_word_i => new_word_i,

Lc_i => Lc_first_s,

Lr_i => Lr_first_s,

Lr_o => Lr_inner_s,

dec_rx_o => open

);

-- last iteration

ldpc_last_iter_block_inst: ldpc_last_iter_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => en_i,

new_word_i => new_word_i,

Lc_i => Lc_first_s,

Page 100: Um estudo sobre a construção, desempenho e …

100

Lr_i => Lr_inner_s,

dec_data_o => dec_data_o

);

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the first iteration of the ldpc decoder.

-- At the first clock pulse occurs Lc and Lq initialization.

-- At the second clock pulse happens Lr update

-- At the third clock pulse decision is performed.

entity ldpc_first_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

rx_i : in row_t;

new_word_i : in std_logic;

-- output

Lc_o : out row_t;

Lq_o : out Lq_t;

Lr_o : out Lr_t;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_first_iter_block;

-- new_word_i : flag to indicate a incoming data.

-- rx_i : ldpc word.

-- Lq_o : Lq matrix

-- Lr_o : Lr matrix

-- dec_rx_o : corrected ldpc word.

Page 101: Um estudo sobre a construção, desempenho e …

101

architecture rtl of ldpc_first_iter_block is

-- Lc vector initialization

component Lc_init_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

rx_i : in row_t;

Lc_o : out row_t

);

end component;

signal Lc_s : row_t;

-- Lq initialization

component Lq_init_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

rx_i : in row_t;

Lq_init_o : out Lq_t

);

end component;

signal Lq_s : Lq_t;

-- Lrji update

component Lr_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lq_i : in Lq_t;

Lr_o : out Lr_t

);

end component;

signal Lr_s : Lr_t;

-- Decision block

component ldpc_decision_block is

port(

Page 102: Um estudo sobre a construção, desempenho e …

102

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

--valid_word_o : out std_logic;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

-- LDPC control block

component ldpc_ctrl_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

new_word_i : in std_logic;

ctrl_pulse_o : out std_logic_vector(2 downto 0)

);

end component;

signal ctrl_pulse_s : std_logic_vector(2 downto 0) := (others => '0');

-- signal enable for the blocks

signal first_pulse_en, second_pulse_en, third_pulse_en : std_logic := '0';

begin

-- signal enables

first_pulse_en <= en_i and ctrl_pulse_s(0);

second_pulse_en <= en_i and ctrl_pulse_s(1);

third_pulse_en <= en_i and ctrl_pulse_s(2);

-- Lc initialization

Lc_init_block_inst: Lc_init_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => first_pulse_en,

rx_i => rx_i,

Lc_o => Lc_s

);

-- Lq initialization

Lq_init_block_inst: Lq_init_block

port map(

Page 103: Um estudo sobre a construção, desempenho e …

103

rst_i => rst_i,

mclk_i => mclk_i,

en_i => first_pulse_en,

rx_i => rx_i,

Lq_init_o => Lq_s

);

-- Lr update

Lr_calc_block_inst: Lr_calc_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => second_pulse_en,

Lq_i => Lq_s,

Lr_o => Lr_s

);

-- decision block

ldpc_decision_block_inst: ldpc_decision_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => third_pulse_en,

Lc_i => Lc_s,

Lr_i => Lr_s,

dec_rx_o => dec_rx_o

);

-- control block

ldpc_ctrl_block_inst: ldpc_ctrl_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => en_i,

new_word_i => new_word_i,

ctrl_pulse_o => ctrl_pulse_s

);

-- output signal

Lc_o <= Lc_s;

Lq_o <= Lq_s;

Lr_o <= Lr_s;

end rtl;

# ----------------------------------------------------------------------------

Page 104: Um estudo sobre a construção, desempenho e …

104

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the following iterations of the ldpc decoder.

-- At the first clock pulse occurs Lq update.

-- At the second clock pulse happens Lr update

-- At the third clock pulse decision is performed.

entity ldpc_middle_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

new_word_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

-- output

Lr_o : out Lr_t;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_middle_iter_block;

-- new_word_i : flag to indicate a incoming data.

-- rx_i : ldpc word.

-- Lq_o : Lq matrix

-- Lr_o : Lr matrix

-- dec_rx_o : corrected ldpc word.

architecture rtl of ldpc_middle_iter_block is

-- Lq update

component Lq_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lr_i : in Lr_t;

Page 105: Um estudo sobre a construção, desempenho e …

105

Lq_o : out Lq_t

);

end component;

signal Lq_s : Lq_t;

-- Lrji update

component Lr_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lq_i : in Lq_t;

Lr_o : out Lr_t

);

end component;

signal Lr_s : Lr_t;

-- Decision block

component ldpc_decision_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

--valid_word_o : out std_logic;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

-- LDPC control block

component ldpc_ctrl_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

new_word_i : in std_logic;

ctrl_pulse_o : out std_logic_vector(2 downto 0)

);

end component;

signal ctrl_pulse_s : std_logic_vector(2 downto 0) := (others => '0');

Page 106: Um estudo sobre a construção, desempenho e …

106

-- signal enable for the blocks

signal first_pulse_en, second_pulse_en, third_pulse_en : std_logic := '0';

begin

-- signal enables

first_pulse_en <= en_i and ctrl_pulse_s(0);

second_pulse_en <= en_i and ctrl_pulse_s(1);

third_pulse_en <= en_i and ctrl_pulse_s(2);

-- Lq update

Lq_calc_block_inst: Lq_calc_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => first_pulse_en,

Lr_i => Lr_i,

Lq_o => Lq_s

);

-- Lr update

Lr_calc_block_inst: Lr_calc_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => second_pulse_en,

Lq_i => Lq_s,

Lr_o => Lr_s

);

-- decision block

ldpc_decision_block_inst: ldpc_decision_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => third_pulse_en,

Lc_i => Lc_i,

Lr_i => Lr_s,

dec_rx_o => dec_rx_o

);

-- control block

ldpc_ctrl_block_inst: ldpc_ctrl_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

Page 107: Um estudo sobre a construção, desempenho e …

107

en_i => en_i,

new_word_i => new_word_i,

ctrl_pulse_o => ctrl_pulse_s

);

-- output signal

Lr_o <= Lr_s;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the last iteration of the ldpc decoder.

-- At the first clock pulse occurs Lq update.

-- At the second clock pulse happens Lr update

-- At the third clock pulse decision is performed.

entity ldpc_last_iter_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

-- input

new_word_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

-- output

dec_data_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_last_iter_block;

-- new_word_i : flag to indicate a incoming data.

-- rx_i : ldpc word.

-- Lc_i : matrix that stores the initial value of rx_i

-- Lr_i : Lr matrix

Page 108: Um estudo sobre a construção, desempenho e …

108

-- dec_data_o : decoded ldpc word.

architecture rtl of ldpc_last_iter_block is

-- Lq update

component Lq_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lr_i : in Lr_t;

Lq_o : out Lq_t

);

end component;

signal Lq_s : Lq_t;

-- Lrji update

component Lr_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lq_i : in Lq_t;

Lr_o : out Lr_t

);

end component;

signal Lr_s : Lr_t;

-- Decision block

component ldpc_decision_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lc_i : in row_t;

Lr_i : in Lr_t;

--valid_word_o : out std_logic;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end component;

-- LDPC control block

Page 109: Um estudo sobre a construção, desempenho e …

109

component ldpc_ctrl_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

new_word_i : in std_logic;

ctrl_pulse_o : out std_logic_vector(2 downto 0)

);

end component;

-- ldpc control signals

signal ctrl_pulse_s : std_logic_vector(2 downto 0) := (others => '0');

-- signal enable for the blocks

signal first_pulse_en, second_pulse_en, third_pulse_en : std_logic := '0';

-- decoded data

signal dec_data_s : std_logic_vector(n_c-1 downto 0):= (others => '0');

begin

-- signal enables

first_pulse_en <= en_i and ctrl_pulse_s(0);

second_pulse_en <= en_i and ctrl_pulse_s(1);

third_pulse_en <= en_i and ctrl_pulse_s(2);

-- Lq update

Lq_calc_block_inst: Lq_calc_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => first_pulse_en,

Lr_i => Lr_i,

Lq_o => Lq_s

);

-- Lr update

Lr_calc_block_inst: Lr_calc_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => second_pulse_en,

Lq_i => Lq_s,

Lr_o => Lr_s

);

-- decision block

Page 110: Um estudo sobre a construção, desempenho e …

110

ldpc_decision_block_inst: ldpc_decision_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => third_pulse_en,

Lc_i => Lc_i,

Lr_i => Lr_s,

dec_rx_o => dec_data_s

);

-- control block

ldpc_ctrl_block_inst: ldpc_ctrl_block

port map(

rst_i => rst_i,

mclk_i => mclk_i,

en_i => en_i,

new_word_i => new_word_i,

ctrl_pulse_o => ctrl_pulse_s

);

-- decoded data

dec_data_o <= dec_data_s;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the initialization of Lc matrix.

entity Lc_init_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

rx_i : in row_t;

Lc_o : out row_t

);

end Lc_init_block;

Page 111: Um estudo sobre a construção, desempenho e …

111

-- rx_i : incoming data

-- Lc_o : matrix Lc

architecture rtl of Lc_init_block is

begin

process(rst_i,mclk_i)

begin

if rst_i = '1' then

Lc_o <= (others => (others => '0'));

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

for j in 0 to n_c-1 loop

Lc_o(j) <= rx_i(j);

end loop;

end if;

end if;

end process;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

entity Lq_init_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

rx_i : in row_t;

Lq_init_o : out Lq_t

);

end Lq_init_block;

architecture rtl of Lq_init_block is

-- Lq array

signal Lq_init_s : Lq_t;

Page 112: Um estudo sobre a construção, desempenho e …

112

begin

process(rst_i,mclk_i)

variable value_col_v : integer;

begin

if rst_i = '1' then

Lq_init_s <= (others => (others => (others => '0')));

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

for j in 1 to k_c loop

for i in 1 to ncol_Hzon_c loop

value_col_v := Hzon_c(j,i);

Lq_init_s(j-1)(i-1) <= rx_i(value_col_v-1);

end loop;

end loop;

end if;

end if;

end process;

Lq_init_o <= Lq_init_s;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the update of Rij.

-- Vertical step

entity Lr_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lq_i : in Lq_t;

Lr_o : out Lr_t

);

end Lr_calc_block;

-- Lq_i: matrix that stores Qij values

Page 113: Um estudo sobre a construção, desempenho e …

113

-- Lr_i: matrix that stores Rij values

architecture rtl of Lr_calc_block is

-- Lrji = min(Lqji) excluding Lqji for the corresponding (j,i)

function lr_update_f(Lq_v : Lq_t)

return Lr_t is

variable min_value_v : std_logic_vector(bit_c-1 downto 0);

variable row_Hver_v, col_Hver_v : integer;

variable Lr_v : Lr_t;

begin

-- It is necessary to walk through the row, excluding the value of (j,i)

for j in 1 to k_c loop

for i in 1 to ncol_Hzon_c loop

-- Minimum value initialization

if i /= 1 then

min_value_v := Lq_v(j-1)(0);

else

min_value_v := Lq_v(j-1)(1);

end if;

-- Getting the minimum value

for l in 1 to ncol_Hzon_c loop

if l /= i then

min_value_v := min_f(min_value_v,Lq_v(j-1)(l-1));

else

min_value_v := min_value_v;

end if;

end loop;

-- Assigning Rji

row_Hver_v := Hzon_c(j,i);

-- The column is searched

col_Hver_v := 0;

for k in 1 to ncol_Hver_c loop

if Hver_c(row_Hver_v,k) = j then

col_Hver_v := k;

end if;

end loop;

Page 114: Um estudo sobre a construção, desempenho e …

114

Lr_v(row_Hver_v-1)(col_Hver_v-1) := min_value_v;

end loop;

end loop;

return Lr_v;

end lr_update_f;

begin

process(rst_i,mclk_i)

variable value_col_v : integer;

begin

if rst_i = '1' then

Lr_o <= (others => (others => (others => '0')));

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

Lr_o <= lr_update_f(Lq_i);

end if;

end if;

end process;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block performs the update of Rij.

-- Vertical step

entity Lq_calc_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

Lq_i : in Lq_t;

Lr_i : in Lr_t;

Lq_o : out Lq_t

);

Page 115: Um estudo sobre a construção, desempenho e …

115

end Lq_calc_block;

-- Lq_i: matrix that stores Qij values

-- Lr_i: matrix that stores Rij values

architecture rtl of Lq_calc_block is

signal Lq_s : Lq_t;

-- function

function lq_update_f(Lr_v: Lr_t; iLq_v : Lq_t)

return Lq_t is

variable Lq_v : Lq_t;

variable row_Hzon_v, col_Hzon_v : integer;

variable sum_value_v : std_logic_vector(bit_c-1 downto 0);

variable old_Lq_value_v, new_Lq_value_v : std_logic_vector(bit_c-1 downto 0);

begin

for j in 1 to n_c loop

for i in 1 to ncol_Hver_c loop

-- It is necessary to walk through the row, excluding the value of (i,j).

-- sum value initialization

sum_value_v := conv_std_logic_vector(0,bit_c);

-- Summing the values

for l in 1 to ncol_Hver_c loop

if l /= i then

sum_value_v := sum_f(sum_value_v,Lr_v(j-1)(l-1));

else

sum_value_v := sum_value_v;

end if;

-- Discovering the place to write at Lq

row_Hzon_v := Hver_c(j,i);

-- The Hzon row is searched in order to find the value of i

for k in 1 to ncol_Hzon_c loop

if Hzon_c(row_Hzon_v,k) = j then

col_Hzon_v := k;

end if;

end loop;

-- The Lq value is read and the updated

Page 116: Um estudo sobre a construção, desempenho e …

116

old_Lq_value_v := iLq_v(row_Hzon_v-1)(col_Hzon_v-1);

new_Lq_value_v := sum_f(old_Lq_value_v,sum_value_v);

Lq_v(row_Hzon_v-1)(col_Hzon_v-1) := new_Lq_value_v;

end loop;

end loop;

end loop;

return Lq_v;

end Lq_update_f;

begin

process(rst_i,mclk_i)

begin

if rst_i = '1' then

Lq_s <= (others => (others => (others => '0')));

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

Lq_s <= lq_update_f(Lr_i, Lq_i);

end if;

end if;

end process;

Lq_o <= Lq_s;

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

library ldpc_lib;

use ldpc_lib.rasc_pkg.all;

-- This block sum up all values of Rji por each colunm and decides what

-- is the new value the ldpc vector.

-- Q(j) = Lc(j) + sumj(Rji)

-- if L(Qj) < 0 c(j) = 1 else c(j) = 0

entity ldpc_decision_block is

port(

rst_i : in std_logic;

Page 117: Um estudo sobre a construção, desempenho e …

117

mclk_i : in std_logic;

en_i : in std_logic;

-- input

Lc_i : in row_t;

Lr_i : in Lr_t;

-- output

--valid_word_o : out std_logic;

dec_rx_o : out std_logic_vector(n_c-1 downto 0)

);

end ldpc_decision_block;

-- Lc_i : matrix that stores the values of rx_i.

-- Lr_i : Lr matrix.

-- valid_word_o : flag that indicates if dec_rx_o is a valid word.

-- dec_rx_o : corrected ldpc word.

architecture rtl of ldpc_decision_block is

-- vector used to perform the decision oof the new value of rx_i

signal Q_s : row_t;

-- function

function Q_update_f(Lc_v: row_t; Lr_v: Lr_t)

return row_t is

variable Q_v : row_t;

variable sum_value_v : std_logic_vector(bit_c-1 downto 0);

begin

for j in 1 to n_c loop

-- It is necessary to walk through the row and sum up all values.

sum_value_v := conv_std_logic_vector(0,bit_c);

-- Summing the values

for k in 1 to ncol_Hver_c loop

sum_value_v := sum_f(sum_value_v,Lr_v(j-1)(k-1));

end loop;

-- Q(j) value

Q_v(j-1) := sum_f(sum_value_v,Lc_v(j-1));

end loop;

Page 118: Um estudo sobre a construção, desempenho e …

118

return Q_v;

end Q_update_f;

begin

-- Calculating Q(j)

process(rst_i,mclk_i)

begin

if rst_i = '1' then

Q_s <= (others => (others => '0'));

dec_rx_o <= (others => '0');

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

Q_s <= Q_update_f(Lc_i, Lr_i);

-- decision

for j in 1 to n_c loop

dec_rx_o(j-1) <= decision_f(Q_s(j-1));

end loop;

end if;

end if;

end process;

-- Decision

--process(Q_s)

--begin

-- for j in 1 to n_c loop

-- if min_f(zero_c,Q_s(j-1)) = Q_s(j-1) then

-- dec_rx_o(j-1) <= '1';

-- else

-- dec_rx_o(j-1) <= '0';

-- end if;

-- end loop;

--end process;

-- syndrome calculation

end rtl;

# ----------------------------------------------------------------------------

library ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_arith.all;

use ieee.numeric_std.all;

Page 119: Um estudo sobre a construção, desempenho e …

119

-- This block performs the update of Rij.

-- Vertical step

entity ldpc_ctrl_block is

port(

rst_i : in std_logic;

mclk_i : in std_logic;

en_i : in std_logic;

new_word_i : in std_logic;

ctrl_pulse_o : out std_logic_vector(2 downto 0)

);

end ldpc_ctrl_block;

-- new_word_i : new incoming data

-- ctrl_pulse_o(0) : first pulse

-- For first iteration: Lc and Lq initialization

-- For following iterations: Lq update

-- ctrl_pulse_o(1) : second pulse

-- Lr update

-- ctrl_pulse_o(2) : third pulse

-- Q update and new vector decision

architecture rtl of ldpc_ctrl_block is

-- state machine that controls the data propagation

type control_t is (idle_st, pulse_1st_st, pulse_2nd_st, pulse_3rd_st);

signal pr_control_mq, nx_control_mq: control_t;

begin

process(pr_control_mq, new_word_i)

begin

case pr_control_mq is

when idle_st =>

if new_word_i = '1' then

nx_control_mq <= pulse_1st_st;

else

nx_control_mq <= idle_st;

end if;

when pulse_1st_st =>

nx_control_mq <= pulse_2nd_st;

when pulse_2nd_st =>

Page 120: Um estudo sobre a construção, desempenho e …

120

nx_control_mq <= pulse_3rd_st;

when pulse_3rd_st =>

if new_word_i = '1' then

nx_control_mq <= pulse_1st_st;

else

nx_control_mq <= idle_st;

end if;

when others =>

nx_control_mq <= idle_st;

end case;

end process;

process(rst_i,mclk_i)

begin

if rst_i = '1' then

pr_control_mq <= idle_st;

elsif mclk_i'event and mclk_i = '1' then

if en_i = '1' then

pr_control_mq <= nx_control_mq;

end if;

end if;

end process;

-- Flags to signalize the pulse in which pulse clock the block is working.

-- first pulse

ctrl_pulse_o(0) <= '1' when pr_control_mq = pulse_1st_st else

'0';

-- second pulse

ctrl_pulse_o(1) <= '1' when pr_control_mq = pulse_2nd_st else

'0';

-- third pulse

ctrl_pulse_o(2) <= '1' when pr_control_mq = pulse_3rd_st else

'0';

end rtl;

# ----------------------------------------------------------------------------

Page 121: Um estudo sobre a construção, desempenho e …

121

ANEXO C – Código-fonte dos arquivos utilizados na validação da simulação dos codificadores e

decodificadores implementados em VHDL.

% ---------------------------------------------------------------------------

% min-sum ldpc decoder

function res = min_sum_ldpc_dec(rx_aux,H);

%% Files

% Lc

fid_Lc = fopen('print_Lc.txt','w');

% Lr

fid_Lr = fopen('print_Lr_tb.txt','w');

fid1_Lr = fopen('print_Lr_hex.txt','w');

% Lq

fid_Lq = fopen('print_Lq_tb.txt','w');

fid1_Lq = fopen('print_Lq_hex.txt','w');

% data output

fid_dout = fopen('decoded_data.txt','w');

fid1_dout = fopen('Q_values_hex.txt','w');

%% Truncating rx

rx = truncate_f(rx_aux);

%%

% rx: received data

% H: sparse matrix

% matrix dimensions

[nrow,ncol] = size(H);

% number of iterations

iter = 1;

% i -> used for colunms

% j -> used for rows

% The matrices Hrow and Hcol are generated from the matrix H.

Page 122: Um estudo sobre a construção, desempenho e …

122

% Hzon -> horizontal step

% Hzon stores the colunm values for each row of H.

% Hzon has dimension ncol x nº1per_row

% Hver -> vertical step

% Hver stores the row values for each colunm of H.

% Hver has dimension nrow x nº1per_col

% Hver and Hzon dimensions depend on the number of 1s per colunm and row.

% Generating Hzon e Hver.

Hzon = hzon_f(H);

Hver = hver_f(H);

[nrow_Hzon,ncol_Hzon] = size(Hzon);

[nrow_Hver,ncol_Hver] = size(Hver);

Lc = zeros(1,ncol);

%% Initialization of Lc(i)

for i = 1:ncol

Lc(i) = rx(i);

end

printf_Lc_matrix_f(rx,fid_Lc);

%% Initialization of Qij

% Lqij = Lci for each i

Lq = zeros(nrow,ncol_Hzon);

for j = 1:nrow % row

for i = 1:ncol_Hzon % colunm

% colunm value is stored at the row of Hver

value_col = Hzon(j,i);

Lq(j,i) = Lc(value_col);

Q(j,i) = Lc(value_col);

end

end

% Imprimo em um arquivo para comparar com a simulação em VHDL.

printf_Lq_init_f(Lq,nrow,ncol_Hzon,fid_Lq,fid1_Lq);

fprintf(fid_Lq,'\n\n\n');

fprintf(fid1_Lq,'\n\n\n');

Page 123: Um estudo sobre a construção, desempenho e …

123

%% Calculation of Rij

% Lrij = min(Lqij), excluding Lqij for the corresponding (i,j).

Lr = zeros(ncol,ncol_Hver);

Lr = Lr_update_f(Lq,Hzon,Hver,nrow,ncol,ncol_Hzon,ncol_Hver,fid_Lr,fid1_Lr);

fprintf(fid_Lr,'\n\n\n');

fprintf(fid1_Lr,'\n\n\n');

%% Update of Q

% Q = Lc

%Q = Lc + sum(Lrij)

Q = Q_update_f(Lc,Lr,ncol,ncol_Hver,fid_dout,fid1_dout)

fprintf(fid_dout,'\n\n\n');

fprintf(fid1_dout,'\n\n\n');

%% Following iterations

for it = 1:iter

%% Calculation of Qij

Lq = Lq_update_f(Lq,Lr,Hzon,Hver,nrow,ncol,ncol_Hzon,ncol_Hver,fid_Lq,fid1_Lq);

fprintf(fid_Lq,'\n\n\n');

fprintf(fid1_Lq,'\n\n\n');

%% Calculation of Rij

Lr = Lr_update_f(Lq,Hzon,Hver,nrow,ncol,ncol_Hzon,ncol_Hver,fid_Lr,fid1_Lr);

fprintf(fid_Lr,'\n\n\n');

fprintf(fid1_Lr,'\n\n\n');

%% Update of Q

Q = Q_update_f(Lc,Lr,ncol,ncol_Hver,fid_dout,fid1_dout);

fprintf(fid_dout,'\n\n\n');

fprintf(fid1_dout,'\n\n\n');

end

res = Lq;

%% Closing the files

fclose(fid_Lc);

Page 124: Um estudo sobre a construção, desempenho e …

124

fclose(fid_Lr);

fclose(fid1_Lr);

fclose(fid_Lq);

fclose(fid1_Lq);

fclose(fid_dout);

fclose(fid1_dout);

% ----------------------------------------------------------------------------

function rx_o = truncate_f(rx)

% Função que trunca um valor real para a representação mais próxima em um

% número binário de 12 bits.

% A representação armazena valores no intervalor [-128,127].

% A parte fracionária tem precisão mínima de 1/8 = 0.0625

% O valor são arredondados para baixo.

% Exemplo: 0,7 -> valor mais próximo: 0.5 + 0.125 + 0.0625 = 0.6875.

[a,n] = size(rx);

rx_o = zeros(1,n);

%%

for j = 1:n

%% Verifico se o número está no intervalo [-128,127]

if rx(j) >= -128 && rx(j) <= 127

real_number = rx(j);

else

if real_number > 127

real_number = 127;

else

real_number = -128;

end

end

%% Sinal

% O bit mais significativo será 1, se o número for negativo, ou 0, caso

% contrário.

if real_number >= 0

bit11 = 0;

Page 125: Um estudo sobre a construção, desempenho e …

125

else

bit11 = 1;

end

%% Parte Inteira

if bit11 == 0

% positive value: arrendondo pra cima

int_value = floor(real_number);

else

% negative value: arredondo pra baixo

int_value = ceil(real_number);

end

%% Parte Fracionária

frac_part = abs(real_number) - abs(int_value);

% Verifico em qual intervalo a parte fracionária se localiza.

if frac_part >= 0 && frac_part < 0.0625

frac_value = 0;

else

if frac_part >= 0.0625 && frac_part < 0.125

frac_value = 0.0625;

elseif frac_part >= 0.125 && frac_part < 0.1875

frac_value = 0.125;

elseif frac_part >= 0.1875 && frac_part < 0.25

frac_value = 0.1875;

elseif frac_part >= 0.25 && frac_part < 0.3125

frac_value = 0.25;

elseif frac_part >= 0.3125 && frac_part < 0.375

frac_value = 0.3125;

elseif frac_part >= 0.375 && frac_part < 0.4375

frac_value = 0.375;

elseif frac_part >= 0.4375 && frac_part < 0.5

frac_value = 0.4375;

elseif frac_part >= 0.5 && frac_part < 0.5625

frac_value = 0.5;

elseif frac_part >= 0.5625 && frac_part < 0.625

frac_value = 0.5625;

elseif frac_part >= 0.625 && frac_part < 0.6875

frac_value = 0.625;

elseif frac_part >= 0.6875 && frac_part < 0.75

frac_value = 0.6875;

elseif frac_part >= 0.75 && frac_part < 0.8125

frac_value = 0.75;

elseif frac_part >= 0.8125 && frac_part < 0.875

frac_value = 0.8125;

Page 126: Um estudo sobre a construção, desempenho e …

126

elseif frac_part >= 0.875 && frac_part < 0.9375

frac_value = 0.875;

else

frac_value = 0.9375;

end

%% Valor Final

if bit11 == 0

value = int_value + frac_value;

else

value = (int_value - frac_value);

end

rx_o(j) = value;

end

% ----------------------------------------------------------------------------

% This function generates a matrix that stores the colunm values for each

% row.

function Hzon = hzon_f(H);

% matrix dimensions

[nrow,ncol] = size(H);

for j = 1:nrow

ihzon = 1;

for i = 1:ncol

if H(j,i) == 1

% the column value is stored

Hzon(j,ihzon) = i;

ihzon = ihzon + 1;

end

end

end

% ----------------------------------------------------------------------------

% This function generates a matrix that stores the colunm values for each

% row.

function Hver = hver_f(H);

Page 127: Um estudo sobre a construção, desempenho e …

127

% matrix dimensions

[nrow,ncol] = size(H);

for i = 1:ncol

iver = 1;

for j = 1:nrow

if H(j,i) == 1

% the column value is stored

Hver(i,iver) = j;

iver = iver + 1;

end

end

end

% ----------------------------------------------------------------------------

function printf_Lc_matrix_f(rx,fid_Lc)

[nrow, ncol] = size(rx);

fprintf(fid_Lc,'rx_i <= (\n');

for j = 1:ncol

s_bin = real2bin_f(rx(j));

if j == ncol

fprintf(fid_Lc,' %d => "%s"\n', j-1, s_bin);

else

fprintf(fid_Lc,' %d => "%s",\n', j-1, s_bin);

end

end

fprintf(fid_Lc,');\n');

% ----------------------------------------------------------------------------

function printf_Lq_init_f(Lq,nrow,ncol_Hzon,fid_Lq,fid1_Lq)

% Imprimo em um arquivo para simular a entrado do bloco Lr_calc_block.vhd

for j = 1:nrow % row

for i = 1:ncol_Hzon % colunm

if j == nrow && i == ncol_Hzon

% binary array

s_bin = real2bin_f(Lq(j,i));

fprintf(fid_Lq,' Lq_i(%d)(%d) => "%s" \n',j-1, i-1, s_bin);

else

Page 128: Um estudo sobre a construção, desempenho e …

128

% binary array

s_bin = real2bin_f(Lq(j,i));

fprintf(fid_Lq,' Lq_i(%d)(%d) => "%s", \n',j-1, i-1, s_bin);

end

end

end

% hexadecimal values

for j = 1:nrow % row

for i = 1:ncol_Hzon % colunm

% to hexadecimal convertion

s_bin = real2bin_f(Lq(j,i));

dec_value = bin2dec(s_bin);

hex_value = dec2hex(dec_value,3);

fprintf(fid1_Lq,'%s ',hex_value);

end

fprintf(fid1_Lq,'\n');

end

% ----------------------------------------------------------------------------

% Calculation of Rij

% Lrij = min(Lqij), excluding Lqij for the corresponding (i,j).

function Lr = Lr_update_f(Lq,Hzon,Hver,nrow,ncol,ncol_Hzon,ncol_Hver,fid_Lr,fid1_Lr)

betaij = abs(Lq);

alfaij = sign(Lq);

% Lrij = min(Lqij), excluding Lqij for the corresponding (i,j).

for j = 1:nrow

for i = 1:ncol_Hzon

% It is necessary to walk through the row, excluding the value of

% (i,j).

% Minimum value initialization

if i ~= 1

min_value = betaij(j,1);

signal = alfaij(j,1);

else

min_value = betaij(j,2);

signal = alfaij(j,2);

end

% Getting the modulus of the minimum value

for l = 1:ncol_Hzon

if l ~= i

if min_value > betaij(j,l)

min_value = betaij(j,l);

Page 129: Um estudo sobre a construção, desempenho e …

129

end

end

signal = signal * alfa(j,l);

end

% Assigning Rij

row_Hver = Hzon(j,i);

% the column is searched

col_Hver = 0;

for k = 1:ncol_Hver

if Hver(row_Hver,k) == j;

%col_Hver = Hver(row_Hver,k)

col_Hver = k;

end

end

Lr(row_Hver,col_Hver) = signal * min_value;

end

end

% The values of the matrix Lr is printed in a file.

for j = 1:ncol

for i = 1:ncol_Hver

s_bin = real2bin_f(Lr(j,i));

fprintf(fid_Lr,' Lr_i(%d)(%d) <= "%s";\n',j-1,i-1,s_bin);

end

end

% hex values file

for j = 1:ncol

for i = 1:ncol_Hver

s_bin = real2bin_f(Lr(j,i));

dec_value = bin2dec(s_bin);

hex_value = dec2hex(dec_value,3);

fprintf(fid1_Lr,'%s ',hex_value);

end

fprintf(fid1_Lr,'\n');

end

% ----------------------------------------------------------------------------

% Q update

function Q = Q_update_f(Lc,Lr,ncol,ncol_Hver,fid_dout,fid1_dout)

dec_data = zeros(1,ncol);

% Q = Lc

Page 130: Um estudo sobre a construção, desempenho e …

130

%Q = Lc + sum(Lrij)

for j = 1:ncol

% percorro a linha

Qsum_value = 0;

for k = 1:ncol_Hver

Qsum_value = Qsum_value + Lr(j,k);

end

Q(j) = Lc(j) + Qsum_value;

end

for j = 1:ncol

if Q(j) >= 0

dec_data(j) = 1;

else

dec_data(j) = 0;

end

end

% Imprimindo os dados

for j = 1:ncol

fprintf(fid_dout,'%d',dec_data(j));

end

for j = 1:ncol

s_bin = real2bin_f(Q(j));

dec_value = bin2dec(s_bin);

hex_value = dec2hex(dec_value,3);

fprintf(fid1_dout,'%s ',hex_value);

end

% ----------------------------------------------------------------------------

function Lq = Lq_update_f(Lq,Lr,Hzon,Hver,nrow,ncol,ncol_Hzon,ncol_Hver,fid_Lq,fid1_Lq)

for j = 1:ncol

for i = 1:ncol_Hver

% It is necessary to walk through the row, excluding the value of

% (i,j).

% sum value initialization

sum_value = 0;

% Summing the values

for l = 1:ncol_Hver

if l ~= i

sum_value = sum_value + Lr(j,l);

else

sum_value = sum_value;

end

Page 131: Um estudo sobre a construção, desempenho e …

131

end

% Discovering the place to write at Lq

row_Hzon = Hver(j,i);

% the Hzon row is searched in order to find the value of i

for k = 1:ncol_Hzon

if Hzon(row_Hzon,k) == j

col_Hzon = k;

end

end

% The Lq value is read and then updated

old_Lq_value = Lq(row_Hzon,col_Hzon);

new_Lq_value = old_Lq_value + sum_value;

Lq(row_Hzon,col_Hzon) = new_Lq_value;

end

end

Lq

% The values of the matrix Lq is printed in a file.

for j = 1:nrow

for i = 1:ncol_Hzon

s_bin = real2bin_f(Lq(j,i));

fprintf(fid_Lq,' Lq_i(%d)(%d) <= "%s";\n',j-1,i-1,s_bin);

end

end

% hex values file

for j = 1:nrow

for i = 1:ncol_Hzon

s_bin = real2bin_f(Lq(j,i));

dec_value = bin2dec(s_bin);

hex_value = dec2hex(dec_value,3);

fprintf(fid1_Lq,'%s ',hex_value);

end

fprintf(fid1_Lq,'\n');

end

% ----------------------------------------------------------------------------