Escolar Documentos
Profissional Documentos
Cultura Documentos
CAMPO MOURÃO
2019
GUILHERME AUGUSTO PASCHOAL DA SILVA
CAMPO MOURÃO
2019
Ministério da Educação
Universidade Tecnológica Federal do Paraná
Campus Campo Mourão
Coordenação de Engenharia Eletrônica
DO(A) DISCENTE
_______________________________________________
Prof. André Luiz Regis Monteiro
UTFPR
_______________________________________________
Prof. Leandro Castilho Brolin
UTFPR
_______________________________________________
Prof. Marcio Rodrigues da Cunha
Orientador
UTFPR
RESUMO
IA Inteligência Artificial
IAS Inteligência Artificial simbólica
IAC Inteligencia Artificial conexionista
RNA Redes Neurais Artificiais
PLD Programmable Logic Devices (Dispositivos Lógicos
Programáveis)
FPGA Field Programmable Gate Array (Matriz de portas programáveis
em campo)
VHDL VHSIC Hardware Description Language (VHSIC Linguagem de
descrição de hardware)
MATLAB® Matrix Laboratory (Laboratório de Matrizes)
CLB Configuration Logical Blocks (Blocos Lógicos de configuração)
DSP Digital Signal Processor (Processador Digital de Sinais)
VHSIC Very High Speed Integrated Circuit (Circuito Integrado de alta
velocidade)
IEEE Institute of Eletrical and Eletronic Engineers (Instituto de
Engenheiros Eletricistas e Eletrônicos)
SUMÁRIO
1 INTRODUÇÃO .............................................................................................. 10
1.1 OBJETIVOS ............................................................................................ 11
1.1.1 OBJETIVO GERAL ............................................................................... 11
1.1.2 OBJETIVOS ESPECÍFICOS ................................................................ 12
1.1.3 JUSTIFICATIVA ................................................................................... 12
2 FUNDAMENTAÇÃO TEÓRICA .................................................................... 13
2.1 REDES NEURAIS ARTIFICIAIS .............................................................. 13
2.1.1 NEURÔNIO BIOLÓGICO ..................................................................... 14
2.1.2 NEURÔNIO ARTIFICIAL ...................................................................... 15
2.1.4 PROCESSOS DE APRENDIZAGEM.................................................... 20
2.1.4.1 APRENDIZAGEM SUPERVISIONADA ............................................. 21
2.1.4.2 APRENDIZAGEM NÃO-SUPERVISIONADA .................................... 21
2.1.5 REDE PERCEPTRON .......................................................................... 22
2.1.6 REDE PERCEPTRON MULTICAMADAS............................................. 25
2.1.7 RECONHECIMENTO E CLASSIFICAÇÃO DE PADRÕES .................. 25
2.2 FPGA ...................................................................................................... 26
2.3 VHDL ....................................................................................................... 27
3 DESENVOLVIMENTO .................................................................................. 29
3.1 DESCRIÇÃO DAS FERRAMENTAS DE SOFTWARE E HARDWARE.... 29
3.2 DATASETS UTILIZADOS........................................................................ 30
3.2.1 DATASET 1 .......................................................................................... 30
3.2.2 DATASET 2 .......................................................................................... 31
3.3 IMPLEMENTAÇÃO NO MATLAB® .......................................................... 32
3.3.1 REDE 1................................................................................................. 32
3.3.2 REDE 2................................................................................................. 34
3.4 IMPLEMENTAÇÃO EM VHDL ................................................................. 37
3.4.1 IMPLEMENTAÇÃO EM VHDL – REDE 1.............................................. 37
3.4.2 IMPLEMENTAÇÃO EM VHDL – REDE 2.............................................. 39
4 RESULTADOS E DISCUSSÕES .................................................................. 45
4.1 CONSUMO DE RECURSOS ................................................................... 45
4.2 COMPARAÇÕES HW X SW .................................................................... 47
5 CONCLUSÕES ............................................................................................. 52
REFERÊNCIAS ................................................................................................ 54
APÊNDICE A – QUADROS DE DADOS ......................................................... 56
APÊNDICE B – SCRIPT PARA SIMULAÇÃO DA REDE 1 ............................ 58
APÊNDICE C – SCRIPT PARA CRIAÇÃO E TREINAMENTO DA REDE 2 ... 59
APÊNDICE D – SCRIPT PARA SIMULAÇÃO DA REDE 2 ............................ 61
APÊNDICE E – BLOCOS QUE COMPÕE O MÓDULO REDE_MLP.............. 63
APÊNDICE F – DESCRIÇÃO DA REDE 1 EM VHDL ..................................... 64
APÊNDICE G – DESCRIÇÃO DA REDE 2 EM VHDL..................................... 73
10
1 INTRODUÇÃO
1.1 OBJETIVOS
1.1.3 JUSTIFICATIVA
2 FUNDAMENTAÇÃO TEÓRICA
𝑣𝑘 = 𝑏𝑘 + ∑𝑛𝑚=1 𝑤𝑚 𝑥𝑚 (2.1)
𝑦𝑘 = 𝜑(𝑣𝑘 ) (2.2)
Figura 3 - Funções de ativação: Função de limiar; Função linear por partes; Função sigmoide.
Para que uma rede neural seja utilizada para a solução de um problema,
o passo inicial é a etapa de aprendizagem. Durante esta fase, a rede extrai
informações do ambiente a qual está introduzida, e cria representações
particulares na forma de pesos sinápticos, associados as conexões entre os
neurônios (WOLF, 2001).
Segundo Braga (2011), existem basicamente dois paradigmas de
aprendizado. O aprendizado supervisionado e o não supervisionado, também
chamados de aprendizagem com um professor e aprendizagem sem um
professor, respectivamente.
21
2.2 FPGA
• Baixo custo;
2.3 VHDL
3 DESENVOLVIMENTO
3.2.1 DATASET 1
A E I O U
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
Fonte: Autoria Própria (2019).
3.2.2 DATASET 2
3.3.1 REDE 1
Para a criação desta rede foi utilizado o banco de dados das letras,
descrito anteriormente. Por ser uma rede simples com uma fácil convergência,
utilizou-se os parâmetros de treinamento indicados pelo próprio MATLAB®, sem
ser necessário muitas alterações.
Por ser uma rede mais simples, utilizou-se o nntool, que é um aplicativo
pertencente ao toolbox de redes neurais. A arquitetura utilizada foi a Perceptron,
ou seja, possui apenas uma camada de neurônios.
A função de ativação escolhida foi o degrau unitário, pois o vetor de
saída desejado é binário, e esta função limita o resultado em apenas 0 ou 1, e
por ser facilmente implementada em hardware. O algoritmo utilizado para a
atualização dos pesos e bias foi o Cyclical order weight/ bias training, pois é
33
3.3.2 REDE 2
de dois do vetor multiplicando-o por -1, tendo o mesmo número com sinal
positivo. Se o número já for positivo, apenas coloca-o na saída.
O próximo bloco é o coeficientes, que através de LUTs, utilizadas para
tabelar os valores dos intervalos em que a entrada está, localiza a qual das retas
o número da entrada pertence e retorna os coeficientes A e B para o cálculo da
mesma.
Por fim, o bloco calculo_reta faz a multiplicação da entrada com o
coeficiente A e depois a soma do resultado com o coeficiente B, tendo assim o
resultado da função. Por último, este bloco compara se a entrada do bloco da
função era negativa, se sim, faz o complemento de dois novamente para obter o
resultado real da função.
Todos os parâmetros dos pesos e bias foram definidos como constantes
em um pacote chamado neuron_types.
4 RESULTADOS E DISCUSSÕES
4.2 COMPARAÇÕES HW x SW
.
Fonte: Autoria Própria (2019).
49
Hardware Software
Rede 1 15,83 ns 343 us
Rede 2 78,83 ns 1,76 ms
Fonte: Autoria Própria (2019).
52
5 CONCLUSÕES
REFERÊNCIAS
A E I O U
0 1 0 0 1
1 1 0 1 1
1 1 0 1 1
1 1 0 1 1
1 1 0 0 0
1 1 1 1 0
0 0 1 0 0
1 1 1 0 0
0 0 1 0 0
0 1 1 1 1
1 1 0 1 0
0 0 0 0 0
1 1 0 0 0
0 0 0 0 0
0 1 0 1 1
0 1 0 0 1
1 0 0 1 1
1 0 0 1 1
1 0 0 1 1
1 1 0 0 0
Fonte: Autoria própria (2019).
A A E E I I O O U U
0 0 1 1 0 0 0 0 1 1
1 1 1 1 1 0 1 0 1 1
1 1 1 1 0 0 1 1 1 0
1 1 1 1 0 0 1 1 1 1
1 1 1 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0
0 0 0 0 1 1 0 0 0 0
1 1 1 1 1 1 0 0 1 0
0 0 0 0 1 0 1 0 0 0
1 0 1 1 1 1 1 1 1 1
1 1 1 1 0 0 1 1 0 0
0 0 1 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0
57
0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 1 1 1 1
0 0 1 1 0 0 0 0 1 1
1 1 0 0 0 0 1 1 1 1
1 1 0 0 0 0 1 1 1 1
1 1 0 0 0 0 1 1 1 1
1 0 1 0 0 0 0 0 0 0
Fonte: Autoria Própria (2019).
58
IW1_1 = [-1 0 0 0 1 0 0 1 0 -2 0 0 1 0 -2 -1 1 1 1 1;
1 0 0 0 0 -1 -1 -1 -1 0 0 0 0 0 1 1 -1 -1 -1 0;
0 -1 -1 -1 -1 0 1 0 1 1 -1 0 -1 0 0 0 -1 -1 -1 -1;
-3 0 0 0 -2 2 -1 -3 -1 1 3 0 -2 0 2 -3 0 0 0 -2;
2 0 0 0 -1 -2 0 -1 0 1 -2 0 -1 0 1 2 0 0 0 -1];
%% Simulação
Q = size(x1,2);
a1 = hardlim_apply(repmat(b1,1,Q) + IW1_1*x1); %
realiza as operações da rede
%% Saída
y1 = a1;
load iris_dataset;
x = irisInputs;
t = irisTargets;
%% Criação da RNA
trainFcn = 'trainlm'; %
Definição do algoritmo de treinamento utilizado
hiddenLayerSize =4; %
quantidade de neurônios na camada oculta
net = feedforwardnet(hiddenLayerSize); %
declaração da rna
%% Treinamento e teste
[net,tr] = train(net,x,t); % treinamento da rede
com os dados selecionados
% Teste da rede
y = net(x);
e = gsubtract(t,y);
performance = perform(net,t,y)
tind = vec2ind(t);
yind = vec2ind(y);
60
% Vizualização da arquitetura
view(net)
% Plots
%figure, plotperform(tr)
%figure, plottrainstate(tr)
%figure, ploterrhist(e)
figure, plotconfusion(t,y)
%figure, plotroc(t,y)
%figure, plotregression(t,y)
%% Parametros da normalização
x1_step1.xoffset = [4.3;2;1;0.1];
x1_step1.gain =
[0.555555555555555;0.833333333333333;0.338983050847458
;0.833333333333333];
x1_step1.ymin = -1;
% Camada de saída
b2 =
[1.7297043950244477;0.037428729205477455;1.21849171315
31301];
LW2_1 = [0.055348544261399714 0.058987318278496903
0.57771621003380391 -1.2310609743526915;-
0.907243601320327 -1.5740265321696392 -
0.42282283933239267 1.1602577928464461;-
0.72839507295651085 0.75431267705990379 -
0.11168872738357107 -0.13374493780096891];
%% Simulação
Q = size(x1,2);
62
a1 = tansig_apply(repmat(b1,1,Q) + IW1_1*xp1); %
Operações realizadas na camada oculta
a2 = tansig_apply(repmat(b2,1,Q) + LW2_1*a1); %
Operações na camada de saída
y1 = mapminmax_reverse(a2,y1_step1); %
Saída
end
%% Funções utilizadas
% Processamento da entrada
function y = mapminmax_apply(x,settings)
y = bsxfun(@minus,x,settings.xoffset);
y = bsxfun(@times,y,settings.gain);
y = bsxfun(@plus,y,settings.ymin);
end
% Tangente Hiperbolica
function a = tansig_apply(n,~)
a = 2 ./ (1 + exp(-2*n)) - 1;
end
% Processamento da saída
function x = mapminmax_reverse(y,settings)
x = bsxfun(@minus,y,settings.ymin);
x = bsxfun(@rdivide,x,settings.gain);
x = bsxfun(@plus,x,settings.xoffset);
end
63
---------------------------------------------------
--Multiplicador
---------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity multiplicador is
port (x : in std_logic_vector (input_size-1 downto
0);
w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w1
7,w18,w19 : in signed (weight_length-1 downto 0);
p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,
p19 : out signed (weight_length-1 downto 0)
);
end multiplicador;
begin
weight_vector(0)<=w0;
weight_vector(1)<=w1;
weight_vector(2)<=w2;
65
weight_vector(3)<=w3;
weight_vector(4)<=w4;
weight_vector(5)<=w5;
weight_vector(6)<=w6;
weight_vector(7)<=w7;
weight_vector(8)<=w8;
weight_vector(9)<=w9;
weight_vector(10)<=w10;
weight_vector(11)<=w11;
weight_vector(12)<=w12;
weight_vector(13)<=w13;
weight_vector(14)<=w14;
weight_vector(15)<=w15;
weight_vector(16)<=w16;
weight_vector(17)<=w17;
weight_vector(18)<=w18;
weight_vector(19)<=w19;
p0<=prod_vector(0);
p1<=prod_vector(1);
p2<=prod_vector(2);
p3<=prod_vector(3);
p4<=prod_vector(4);
p5<=prod_vector(5);
p6<=prod_vector(6);
p7<=prod_vector(7);
p8<=prod_vector(8);
p9<=prod_vector(9);
p10<=prod_vector(10);
66
p11<=prod_vector(11);
p12<=prod_vector(12);
p13<=prod_vector(13);
p14<=prod_vector(14);
p15<=prod_vector(15);
p16<=prod_vector(16);
p17<=prod_vector(17);
p18<=prod_vector(18);
p19<=prod_vector(19);
end hardware;
-----------------------------------
-- Acumulador
-----------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity acumulador is
port
(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19
: in signed (weight_length-1 downto 0);
bias
: in signed
(2*weight_length-1 downto 0);
sigma
: out signed
(2*weight_length-1 downto 0)
);
end acumulador;
67
begin
prod_vector(0)<=p0;
prod_vector(1)<=p1;
prod_vector(2)<=p2;
prod_vector(3)<=p3;
prod_vector(4)<=p4;
prod_vector(5)<=p5;
prod_vector(6)<=p6;
prod_vector(7)<=p7;
prod_vector(8)<=p8;
prod_vector(9)<=p9;
prod_vector(10)<=p10;
prod_vector(11)<=p11;
prod_vector(12)<=p12;
prod_vector(13)<=p13;
prod_vector(14)<=p14;
prod_vector(15)<=p15;
prod_vector(16)<=p16;
prod_vector(17)<=p17;
prod_vector(18)<=p18;
prod_vector(19)<=p19;
aux_acum(0)<=bias;
gen1: for i in 0 to input_size-1 generate
aux_acum(i+1)<= prod_vector(i) + aux_acum(i);
68
end generate;
sigma<= aux_acum(input_size);
end hardware;
-----------------------------------
--Função de ativação
---------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity hardlim is
port (sigma : in signed (2*weight_length-1 downto 0);
y : out std_logic
);
end hardlim;
begin
end hardware;
---------------------------
--neuronio
---------------------------
library ieee;
use ieee.std_logic_1164.all;
69
use ieee.numeric_std.all;
use work.neuron_types.all;
entity neuronio is
port (x : in std_logic_vector (input_size-1
downto 0);
w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w1
7,w18,w19: in signed (weight_length-1 downto 0);
bias : in signed (2*weight_length-1 downto 0);
y : out std_logic
);
end neuronio;
component multiplicador is
port (x : in std_logic_vector (input_size-1 downto
0);
w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w1
7,w18,w19 : in signed (weight_length-1 downto 0);
p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,
p19 : out signed (weight_length-1 downto 0)
);
end component;
component acumulador is
port
(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19
: in signed (weight_length-1 downto 0);
70
bias
: in signed
(2*weight_length-1 downto 0);
sigma
: out signed
(2*weight_length-1 downto 0)
);
end component;
component hardlim is
port (sigma : in signed (2*weight_length-1 downto 0);
y : out std_logic
);
end component;
signal pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7, pd8, pd9, pd10, pd11, pd12, pd13,
pd14, pd15, pd16, pd17, pd18, pd19 : signed (weight_length-1
downto 0);
signal aux_sigma : signed (2*weight_length-1 downto 0);
begin
end ligacoes;
71
----------------------------------
--Rede neural
----------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity rede_neural is
port (x : in std_logic_vector (0 to input_size-1);
y : out std_logic_vector (0
to 4)
);
end rede_neural;
w0,w1,w2,w3,w4,w5,w6,w7,w8,w9,w10,w11,w12,w13,w14,w15,w16,w1
7,w18,w19: in signed (weight_length-1 downto 0);
bias : in signed (2*weight_length-1 downto 0);
y : out std_logic
);
end component;
begin
end ligacoes;
73
-------------------------------------------------
--Pacote de dados com pesos e bias
------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package neuron_types is
constant input_size : natural :=4;
--quantidade de entradas de cada neuronio
constant input_length : natural :=12;
--tamanho dos dados de entrada
constant output_size : natural :=3;
--quantidade de saidas de cada neuronio
constant output_length : natural :=12;
--tamanho dos dados de saida
constant n_camada_oculta: natural :=4;
-- quantidade de neuronios na camada oculta
constant n_camada_saida : natural :=3;
-- quantidade de neuronios na camada de saida;
-- bias :
CONSTANT b_0 : signed (input_length+output_length-1 downto
0):="000000011101001101101000";
75
end neuron_types;
------------------------------------
--bloco offset na entrada
---------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
begin
sig0<=i_0-aux0;
sig1<=i_1-aux1;
sig2<=i_2-aux2;
sig3<=i_3-aux3;
o_0<=sig0;
o_1<=sig1;
o_2<=sig2;
o_3<=sig3;
end hardware;
-----------------------------------
--bloco times
-----------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
78
entity times is
port ( i_0, i_1, i_2, i_3 : in signed
(input_length-1 downto 0);
o_0, o_1, o_2, o_3 : out
signed (input_length-1 downto 0)
);
end times;
begin
sig0<=i_0*aux0;
sig_0<=sig0(19) & sig0(18 downto 16) & sig0(15 downto 8);
sig1<=i_1*aux1;
sig_1<=sig1(19) & sig1(18 downto 16) & sig1(15 downto 8);
sig2<=i_2*aux2;
sig_2<=sig2(19) & sig2(18 downto 16) & sig2(15 downto 8);
79
sig3<=i_3*aux3;
sig_3<=sig3(19) & sig3(18 downto 16) & sig3(15 downto 8);
o_0<=sig_0;
o_1<=sig_1;
o_2<=sig_2;
o_3<=sig_3;
end hardware;
---------------------------------------
--bloco plus
---------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity plus is
port ( i_0, i_1, i_2, i_3 : in signed
(input_length-1 downto 0);
o_0, o_1, o_2, o_3 : out
signed (input_length-1 downto 0)
);
end plus;
begin
sig0<=i_0+aux0;
sig1<=i_1+aux1;
sig2<=i_2+aux2;
sig3<=i_3+aux3;
o_0<=sig0;
o_1<=sig1;
o_2<=sig2;
o_3<=sig3;
end hardware;
--------------------------------
-- bloco normalizador
----------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity bloco_normalizador is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
out0, out1, out2, out3 : out signed
(output_length-1 downto 0)
);
end bloco_normalizador;
component times is
port ( i_0, i_1, i_2, i_3 : in signed
(input_length-1 downto 0);
o_0, o_1, o_2, o_3 : out
signed (input_length-1 downto 0)
);
end component;
component plus is
port ( i_0, i_1, i_2, i_3 : in signed
(input_length-1 downto 0);
o_0, o_1, o_2, o_3 : out
signed (input_length-1 downto 0)
);
end component;
---------------------------------------------------------------------------------------
signal sig_off0, sig_off1, sig_off2, sig_off3 : signed (input_length-1
downto 0);
signal sig_tim0, sig_tim1, sig_tim2, sig_tim3 : signed (input_length-1
downto 0);
---------------------------------------------------------------------------------------
begin
bloco_offset : offset PORT MAP (x0, x1, x2, x3, sig_off0, sig_off1, sig_off2,
sig_off3);
bloco_time : times PORT MAP (sig_off0, sig_off1, sig_off2, sig_off3,
sig_tim0, sig_tim1, sig_tim2, sig_tim3);
82
--------------------------------------
--Multiplicador
--------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity multiplicador is
port (x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3 :
in signed (output_length-1 downto 0);
prod0, prod1, prod2, prod3 : out
signed (input_length+output_length-1 downto 0)
);
end multiplicador;
begin
aux_x(0)<=x0;
aux_x(1)<=x1;
aux_x(2)<=x2;
aux_x(3)<=x3;
aux_w(0)<=w0;
aux_w(1)<=w1;
aux_w(2)<=w2;
aux_w(3)<=w3;
prod0<=aux_prod(0);
prod1<=aux_prod(1);
prod2<=aux_prod(2);
prod3<=aux_prod(3);
end hardware;
-------------------------------------------------
--Acumulador
-------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity acumulador is
port (prod0, prod1, prod2, prod3 : in
signed (input_length+output_length-1 downto 0);
84
bias
: in signed
(input_length+output_length-1 downto 0);
acum
: out signed
(input_length+output_length-1 downto 0)
);
end acumulador;
begin
aux_prod(0)<=prod0;
aux_prod(1)<=prod1;
aux_prod(2)<=prod2;
aux_prod(3)<=prod3;
aux_acum(0)<=bias;
acum<=aux_acum(input_size);
end hardware;
85
---------------------------------------
--bloco operações lineares
--------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity operacoes_lineares is
port (x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3 :
in signed (output_length-1 downto 0);
bias
: in signed
(input_length+output_length-1 downto 0);
sigma
: out signed (input_length+output_length-1
downto 0)
);
end operacoes_lineares;
component multiplicador is
port (x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3 :
in signed (output_length-1 downto 0);
prod0, prod1, prod2, prod3 : out
signed (input_length+output_length-1 downto 0)
);
end component;
86
component acumulador is
port (prod0, prod1, prod2, prod3 : in
signed (input_length+output_length-1 downto 0);
bias
: in signed
(input_length+output_length-1 downto 0);
acum
: out signed
(input_length+output_length-1 downto 0)
);
end component;
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
BEGIN
bloco_multiplicador: multiplicador PORT MAP (x0, x1, x2, x3, w0, w1, w2, w3,
s_prod0, s_prod1, s_prod2, s_prod3);
end hardware;
----------------------------------------
--complemento de 2
---------------------------------------
library ieee;
87
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity complemento_2 is
port ( complem_in : in
signed (input_length+output_length-1 downto 0);
complem_out : out signed
(input_length+output_length-1 downto 0)
);
end complemento_2;
begin
-- multiplica por -1
aux_complem1<= aux_complem0(39) & aux_complem0(38 downto 32)
& aux_complem0(31 downto 16); -- salva apenas o necessário da multiplicação
(complemento de dois)
"000000000000000000000000";
end hardware;
88
---------------------------------------------
--calculo dos coeficientes
--------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity coeficientes is
port (complem_2 : in signed
(input_length+output_length-1 downto 0);
coef_A : out signed
(input_length+output_length-1 downto 0);
coef_B : out signed
(input_length+output_length-1 downto 0)
);
end coeficientes;
begin
coef_A <="000000001110111000000111" when
complem_2>"000000000000000000000000" AND
complem_2<="000000000111101100001000" else -- reta 1
"000000001011100000100100" when
complem_2>"000000000111101100001000" AND
complem_2<="000000001011001010010101" else -- reta 2
"000000001000011001011001" when
complem_2>"000000001011001010010101" AND
complem_2<="000000010000000000000000" else -- reta 3
"000000000101011111010101" when
complem_2>"000000010000000000000000" AND
complem_2<="000000010100001110010101" else -- reta 4
89
"000000000011010011110000" when
complem_2>"000000010100001110010101" AND
complem_2<="000000011001100110011001" else -- reta 5
"000000000001110010000100" when
complem_2>"000000011001100110011001" AND
complem_2<="000000011111000010101010" else -- reta 6
"000000000000110100001110" when
complem_2>"000000011111000010101010" AND
complem_2<="000000100110111100011010" else -- reta 7
"000000000000010010100010" when
complem_2>"000000100110111100011010" AND
complem_2<="000000110000000000000000" else -- reta 8
"000000000000000010011101" when
complem_2>"000000110000000000000000" AND
complem_2<="000001010000000000000000" else -- reta 9
"000000000000000000000000";
"000000001011111000111011" when
complem_2>"000000011001100110011001" AND
complem_2<="000000011111000010101010" else -- reta 6
"000000001101110001001001" when
complem_2>"000000011111000010101010" AND
complem_2<="000000100110111100011010" else -- reta 7
"000000001111000011010001" when
complem_2>"000000100110111100011010" AND
complem_2<="000000110000000000000000" else -- reta 8
"000000001111110011100111" when
complem_2>"000000110000000000000000" AND
complem_2<="000001010000000000000000" else -- reta 9
"000000010000000000000000"; -- alterei aqui , antes
era tudo zero
end hardware;
------------------------------------------
--calculo da reta
-----------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity calculo_reta is
port ( sigma : in signed
(input_length+output_length-1 downto 0);
complem_2 : in signed
(input_length+output_length-1 downto 0);
coef_A : in signed
(input_length+output_length-1 downto 0);
coef_B : in signed
(input_length+output_length-1 downto 0);
91
begin
end hardware;
--------------------------------
--bloco função tangente hiperbólica
---------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity tangente_hiperbolica is
port ( sigma : in
signed (input_length+output_length-1 downto 0);
y :
out signed (output_length-1 downto 0)
);
end tangente_hiperbolica;
component complemento_2 is
port ( complem_in : in
signed (input_length+output_length-1 downto 0);
complem_out : out signed
(input_length+output_length-1 downto 0)
);
93
end component;
component coeficientes is
port (complem_2 : in signed
(input_length+output_length-1 downto 0);
coef_A : out signed
(input_length+output_length-1 downto 0);
coef_B : out signed
(input_length+output_length-1 downto 0)
);
end component;
component calculo_reta is
port ( sigma : in signed
(input_length+output_length-1 downto 0);
complem_2 : in signed
(input_length+output_length-1 downto 0);
coef_A : in signed
(input_length+output_length-1 downto 0);
coef_B : in signed
(input_length+output_length-1 downto 0);
resultado : out signed
(output_length-1 downto 0)
);
end component;
---------------------------------------------------------------------------------------
signal sig_complem_2 : signed
(input_length+output_length-1 downto 0);
signal sig_coef_A, sig_coef_B : signed (input_length+output_length-1 downto
0);
---------------------------------------------------------------------------------------
begin
94
end hardware;
-----------------------------------
--bloco do neurônio
----------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity neuronio is
port ( x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3
: in signed (output_length-1 downto 0);
bias
: in signed
(input_length+output_length-1 downto 0);
y
: out signed (output_length-1
downto 0)
);
end neuronio;
component operacoes_lineares is
port (x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3 :
in signed (input_length-1 downto 0);
bias
: in signed
(input_length+output_length-1 downto 0);
sigma
: out signed (input_length+output_length-1
downto 0)
);
end component;
component tangente_hiperbolica is
port ( sigma : in
signed (input_length+output_length-1 downto 0);
y :
out signed (output_length-1 downto 0)
);
end component;
---------------------------------------------------------------------------------------------------
signal sig_sigma : signed (input_length+output_length-1 downto 0);
---------------------------------------------------------------------------------------------------
begin
end hardware;
96
-------------------------------------------
--bloco camada oculta
------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity camada_oculta is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
-- dados de entrada
w0,w1,w2,w3
: in signed (input_length-1 downto 0);
w4,w5,w6,w7
: in signed (input_length-1 downto 0);
w8,w9,w10,w11 :
in signed (input_length-1 downto 0);
w12,w13,w14,w15 :
in signed (input_length-1 downto 0);
b0,b1,b2,b3
: in signed (input_length+output_length-1
downto 0);
y0, y1, y2, y3 :
out signed (output_length-1 downto 0)
);
end camada_oculta;
component neuronio is
port ( x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
97
bias
: in signed
(input_length+output_length-1 downto 0);
y
: out signed (output_length-1
downto 0)
);
end component;
--------------------------------------------------------------------------------------------------------
begin
----------------------------------------
--bloco camada de saída
---------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity camada_saida is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
-- dados de entrada
98
w0,w1,w2,w3
: in signed (input_length-1 downto 0);
w4,w5,w6,w7
: in signed (input_length-1 downto 0);
w8,w9,w10,w11 :
in signed (input_length-1 downto 0);
b0,b1,b2
: in signed
(input_length+output_length-1 downto 0);
y4, y5, y6
: out signed (output_length-1 downto 0)
);
end camada_saida;
component neuronio is
port ( x0, x1, x2, x3 :
in signed (input_length -1 downto 0);
w0, w1, w2, w3
: in signed (output_length-1 downto 0);
bias
: in signed
(input_length+output_length-1 downto 0);
y
: out signed (output_length-1
downto 0)
);
end component;
--------------------------------------------------------------------------------------------------------
begin
99
end hardware;
----------------------------
--bloco rede mlp
----------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity rede_mlp is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
-- dados de entrada
y1, y2, y3
: out signed (input_length-1 downto 0)
);
end rede_mlp;
component camada_oculta is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
-- dados de entrada
100
w0,w1,w2,w3
: in signed (input_length-1 downto 0);
w4,w5,w6,w7
: in signed (input_length-1 downto 0);
w8,w9,w10,w11 :
in signed (input_length-1 downto 0);
w12,w13,w14,w15 :
in signed (input_length-1 downto 0);
b0,b1,b2,b3
: in signed (input_length+output_length-1
downto 0);
y0, y1, y2, y3 :
out signed (output_length-1 downto 0)
);
end component;
component camada_saida is
port ( x0, x1, x2, x3 : in
signed (input_length-1 downto 0);
-- dados de entrada
w0,w1,w2,w3
: in signed (input_length-1 downto 0);
w4,w5,w6,w7
: in signed (input_length-1 downto 0);
w8,w9,w10,w11 :
in signed (input_length-1 downto 0);
b0,b1,b2
: in signed
(input_length+output_length-1 downto 0);
y4, y5, y6
: out signed (output_length-1 downto 0)
);
end component;
101
--------------------------------------------------------------------------------------------
signal sig_y0, sig_y1, sig_y2, sig_y3 : signed (output_length-1 downto 0);
--------------------------------------------------------------------------------------------
begin
end hardware;
------------------------------
--bloco de saída
------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.neuron_types.all;
entity decoder is
port ( in_dec0, in_dec1, in_dec2 : in signed (input_length-1 downto 0);
dec0, dec1, dec2 : out
std_logic
);
end decoder;
begin
aux<= "001" WHEN in_dec2 > in_dec0 AND in_dec2 > in_dec1 ELSE
"010" WHEN in_dec1 > in_dec0 AND in_dec1 > in_dec2 ELSE
"100" WHEN in_dec0 > in_dec1 AND in_dec0 > in_dec1 ELSE
"000";
dec0<=aux(2);
dec1<=aux(1);
dec2<=aux(0);
end hardware;