Você está na página 1de 25

UNIVERSIDADE FEDERAL DA BAHIA

ESCOLA POLITÉCNICA
DEPARTAMENTO DE ENGENHARIA ELÉTRICA

Lucas Moura

Victor Gabriel Fagundes

GERADOR DE FORMA DE ONDA SENOIDAL UTILIZANDO ROM E DAC

RELATÓRIO DA ETAPA II DO PROJETO SEMESTRAL DA DISCIPLINA


LABORATÓRIO INTEGRADO III

SALVADOR

2021

1
GERADOR DE FORMA DE ONDA SENOIDAL UTILIZANDO ROM E DAC
Deseja-se, a partir de palavras binárias, as quais correspondem a valores de
tensão de amostras regulares referentes a uma senoide, desenvolver um gerador
senoidal. Desse modo, o sistema projetado conta com duas etapas: (a) tratamento
digital; (b) tratamento digital-analógico; (c) filtro.
Na etapa (a), há uma caixa preta, denominada bloco digital, formada por uma
memória ROM, no qual são armazenados os valores de tensão, e um módulo contador,
no qual é aplicado um sinal de relógio (clock) com período equivalente ao intervalo entre
amostras consecutivas de uma forma de onda senoidal.
As palavras binárias obtidas na etapa (a) são enviadas para o estágio (b),
representado por um conversor digital-analógico (DAC) e, portanto, onde os dados
obtidos serão convertidos em um sinal de tensão analógico, que é, então, encaminhado
a um filtro. Na Fig.1 é possível observar a metodologia descrita.

Fig. 1 – Componentes do gerador senoidal.


Este relatório consiste em uma apresentação sucinta dos resultados obtidos
através da simulação no ambiente PartQuest do gerador de forma senoidal, como
também de sua expansão em um gerador trifásico.

BLOCO DIGITAL
O bloco digital é um sistema essencialmente formado por uma memória ROM e
por um módulo contador de 8 bits. A partir de um sinal de relógio com frequência fclk, o
contador gera palavras binárias de ordem crescente, as quais são fornecidas como
entradas de endereço da memória ROM. Na Fig.2 consta uma representação desse
subsistema.

Fig. 2 – Representação do bloco digital.

Como o sinal de clock do contador foi obtido a partir de um sinal de relógio com
frequência fosc = 5 MHz, valor superior a frequência de 200 Hz da onda senoidal, foi
2
acoplado ao bloco digital um divisor de frequência (Fig.3), responsável adequar o sinal
ao intervalo desejado, como também permitir, através dos bits S3, S2, S1, S0, um ajuste
fino em torno da frequência de interesse.

Fig. 3 – Divisor de frequência do sinal de clock.


No caso da combinação S3 = S0 = ‘0’ e S2 = S1 = ‘1’, obteve-se, considerando 50
amostras armazenadas na ROM, conforme a Fig.4.1, um sinal, representado em roxo,
com frequência de 10.63830 kHz.

Fig. 4.1 – Resposta do divisor de frequência do sinal de clock para S 3 = S0 = ‘0’; S2 = S1 = ‘1’ (50 pontos).
Já para S3 = S0 = S2 = S1 = ‘0’, foi obtido um sinal com frequência de 10 kHz,
que corresponde a divisão nominal do sistema para 50 amostras referentes aos
valores de tensão da senoide em um período, isto é, 50 x 200 Hz.

Fig. 4.2 – Resposta do divisor de frequência do sinal de clock para S 3 = S0 = S2 = S1 = ‘0’ (50 pontos).
No caso da combinação S3 = S0 = ‘1’ e S2 = S1 = ‘0’, foi obtida, considerando
novamente 50 pontos armazenados na ROM, um sinal com frequência de 9.09091 kHz
(Fig.4.3). Ainda, os scripts utilizados para divisão e as adaptações para números
diferentes de amostras, como é o caso de n1 = 25 e n2 = 100, encontram-se,
respectivamente, nos anexos I, II e III.

3
Fig. 4.3 – Resposta do divisor de frequência do sinal de clock para S 3 = S0 = ‘1’; S2 = S1 = ‘0’ (50 pontos).

Contudo, a equivalência entre os valores teóricos e práticos na divisão de


frequência da onda quadrada não se repetiu na onda senoidal formada pelas amostras
armazenadas na ROM, de forma que os valores de frequência medidos apresentaram
pequenas discrepâncias em relação previstos teoricamente.

Fig. 5.1 – Resposta do gerador para S3 = S0 = S2 = S1 = ‘0’ (50 pontos).


Conforme a Fig.5.1, observa-se que a frequência do clock de saída do divisor é
de 10 kHz, o que, ao utilizar 50 pontos, implicaria teoricamente em uma senoide de 200
Hz. No entanto, a frequência da senoide fornecida pelo DAC foi de 196.07863 Hz, isto
é, há um desvio de 3.92317 Hz para menos.
Dessa forma, foi necessário um ajuste fino no bloco divisor para valores acima
da frequência nominal. Durante a fase testes, a combinação S3 = S0 = S1 = ‘0’; S2 = ‘1’
ocasionou senoides com valores de frequência mais próximos dos teoricamente obtidos
(Fig. 5.2), sendo, portanto, a combinação de referência do divisor de frequência.

Fig. 5.2 – Resposta do gerador para S3 = S0 =S1 = ‘0’; S2 = ‘1’ (50 pontos).

4
CONVERSOR ANALÓGICO-DIGITAL(DAC)
Um conversor nada mais é que um circuito capaz de transformar um sinal, de
acordo com as especificações desejadas. Neste caso, palavras binárias, dadas através
da saída de 8 bits de uma memória ROM, são convertidas em um sinal de tensão
analógico.
A primeira etapa da criação do DAC é a implementação de uma rede R-2R,
exemplificada no circuito da Fig. 6, no qual os bits, do mais significativo ao menos
significativo, controlam chaves que definem a presença da contribuição de corrente em
cada ramo.

Fig. 6 – Rede R-2R.


O valor de R foi convenientemente escolhido como R = 10kΩ. No caso tensão
de referência adotada ser, por conta das palavras binárias da ROM, de 15V, a corrente
máxima calculada na saída, somando as duas componentes será de aproximadamente
1,5mA.

𝑉𝑟𝑒𝑓 (𝑒𝑛𝑡𝑟𝑎𝑑𝑎 𝑑𝑖𝑔𝑖𝑡𝑎𝑙)10


𝐼𝑜𝑢𝑡1 = ∗ (1)
𝑅 256

𝑉𝑟𝑒𝑓 255− (𝑒𝑛𝑡𝑟𝑎𝑑𝑎 𝑑𝑖𝑔𝑖𝑡𝑎𝑙)10


𝐼𝑜𝑢𝑡2 = 𝑅
∗ 256
(2)

Na saída da rede, um amplificador operacional é acoplado, com a função de


transformar esse sinal em um sinal de tensão. Foi escolhido o modelo LM741, por ter
faixa de operação superior aos 15V da tensão de referência.

Fig. 7 – Rede R-2R acoplada a um amplificador.

Porém, o primeiro estágio de amplificação garante somente um sinal unipolar, o


que não representa corretamente uma onda senoidal. Desse modo, é acoplado mais

5
um amplificador, com a função de somador, para deslocar o sinal e atingir o resultado
esperado. O circuito completo pode ser visto na Fig. 8.

Fig. 8 – Bloco DAC completo com 2 estágios de amplificação.


A fim de verificar o desempenho do circuito, um contador de 8 bits foi acoplado
como entrada da rede, de forma que as saídas resultaram no esperado (Fig. 9).

Fig. 9 – Diagrama temporal do DAC utilizando contador de 8 bits com entrada.


A Fig. 9 demonstra o comportamento esperado nas saídas dos amplificadores
do DAC, em que a saída do primeiro estágio em azul se mostra invertida e unipolar. Já
no segundo estágio, em vermelho, o sinal não está invertido, mas sim deslocado para
cima.
Outro ponto importante a se destacar é que para se obter o resultado esperado
no segundo estágio, é necessário inverter o bit mais significativo da entrada, pois os
pontos na ROM são representados em complemento de 2. A equação 3 representa
fórmula utilizada para calcular a tensão que cada ponto.

(𝐸𝑛𝑡𝑟𝑎𝑑𝑎 𝐷𝑖𝑔𝑖𝑡𝑎𝑙)10
𝑉𝑜𝑢𝑡 = 𝑉𝑟𝑒𝑓 * (2 * 256
-1 ) (3)

GERADOR SENOIAL SEM FILTRO

6
Com o projeto elaborado, foram feitas uma série de simulações. Inicialmente
foram analisados resultados obtidos diretamente da saída do DAC. Em cada simulação
foram cedidas entradas diferentes na ROM, com número de pontos, tensão de
referência e amplitudes diferentes.
O primeiro conjunto de simulações, que pode ser visualizado nas Figs.10.1, 10.2
e 10.3, adota tensão de referência de 10V, amplitude da senoide de 8V e número de
amostras de 25, 50 e 100, respectivamente.

Fig. 10.1 – Diagrama temporal da saída do DAC, com entrada de 25 pontos na ROM (V ref = 10V, Amp = 8V).

Fig. 10.2 – Diagrama temporal da saída do DAC, comentrada de 50 pontos na ROM (Vref = 10V, Amp = 8V).

Fig. 10.3 – Diagrama temporal da saída do DAC, com entrada de 50 pontos na ROM (V ref = 10V, Amp = 8V).

É possível observar que a saída do DAC apresenta um degrau, que, por sua vez,
diminui a fidelidade com o sinal esperado. No entanto, quanto maior a amostragem,
menos acentuada é essa distorção.

7
Já o segundo conjunto de simulações apresenta tensão de referência de 10V e
amplitude da senoide também de 10 V. Novamente, são utilizados os valores de 25, 50
e 100 (Figs.11.1, 11.2 e 11.3) para números de amostras.

Fig. 11.1 – Diagrama temporal da saída do DAC, com entrada de 25 pontos na ROM (V ref = 10V, Amp = 10V).

Fig. 11.2 – Diagrama temporal da saída do DAC, com entrada de 50 pontos na ROM (V ref = 10V, Amp = 10V).

Fig. 11.3 – Diagrama temporal da saída do DAC, com entrada de 100 pontos na ROM (V ref = 10V, Amp = 10V).

Os resultados demonstram que a equivalência entre a tensão de referência e


amplitude da senoide ocasionam uma distorção na saída do DAC. Esse comportamento
é comum em circuitos que utilizam amplificadores operacionais, visto que, quando a
tensão aplicada se aproxima da alimentação, que nesse caso corresponde a referencial,
o componente satura e fixa o sinal no máximo valor possível.
Por fim, no último conjunto de simulações, a tensão de referência é elevada para
15V e a amplitude da senoide para 12V. Já o número de amostras novamente 25, 50 e
100 (Figs.12.1, 12.2 e 12.3).
8
Fig. 12.1 – Diagrama temporal da saída do DAC, com entrada de 25 pontos na ROM (V ref = 15V, Amp = 12V).

Fig. 12.2 – Diagrama temporal da saída do DAC, com entrada de 50 pontos na ROM (Vref = 15V, Amp = 12V).

Fig. 12.3 – Diagrama temporal da saída do DAC, com entrada de 100 pontos na ROM (Vref = 15V, Amp = 12V).

Por fim conforme o esperado, ao aumentar a tensão de referência o valor da


amplitude da senoide pode ampliar, sem ocorrer distorção. Outro ponto a ser destacado
é que a senoide simulada com uma fonte ideal, isto é, o sinal vermelho, tem frequência
exata de 200Hz, já as saídas do DAC apresentam alguns pequenos desvios, por isso
não estão sincronizados.

GERADOR SENOIDAL COM FILTRO


A saída do DAC como visto anteriormente apresenta degraus indesejados. Para
resolver este problema um filtro passa baixa foi projetado, a frequência de corte
escolhida para o projeto foi igual à da senoide, sabendo que pela equação 4, a tensão
9
de saída nesse ponto será próxima da esperada, a partir daí será mais fácil valores para
a senoide atingir 8V de pico.
𝑉𝑖𝑛
𝑉𝑜𝑢𝑡 = (4)
√2

12
𝑉𝑜𝑢𝑡 = = 8,485𝑉 (4.1)
√2

1
𝑓𝑐 = 2𝜋𝑅𝐶
(5)

1
200 𝐻𝑧 = 2𝜋∗𝑅∗100𝑛𝐹
(5.1)

𝑅 = 7,957𝑘Ω (5.2)

Por conveniência, o valor do capacitor C foi arbitrado em 100nF, a partir daí e do


primeiro valor de resistência encontrado na equação 5.2, o resistor R foi ajustado, para
que a atenuação do sinal atingisse 8V no pico o valor encontrado foi de 8,9kΩ. O filtro e
o diagrama temporal da saída podem ser vistos na Fig. 13.

Fig. 13 – Diagrama temporal da saída do filtro passa baixa.

Foi observado que o uso deste filtro só é recomendado no caso da fonte sem
carga, pois filtros passivos, principalmente de primeira ordem, não costumam ser
robustos, podendo apresentar perdas significativas, dependendo da drenagem de
corrente na saída.
Recomendasse então, caso necessite acoplar uma carga na saída gerador,
projetar um filtro ativo, sabendo que estes, por conta do uso de amplificadores
operacionais, adicionam ganho a saída, evitando perdas significativas.

10
A escolha da frequência de corte utilizada no projeto foi baseada no seguinte
procedimento foram projetados filtros acima e abaixo da frequência de amostragem 𝑓𝑎
= 200Hz.Para isso as frequências escolhidas foram de 150Hz, 200Hz, 250Hz e 500Hz
respectivamente representadas nas (Figs 14.1, 14.2. 14.3 e 14.4).

Fig. 14.1 – Saída do com 150Hz de frequência de corte.

Fig. 14.2 – Saída do com 200Hz de frequência de corte.

Fig. 14.3 – Saída do com 250Hz de frequência de corte.


11
Fig. 14.4 – Saída do com 500Hz de frequência de corte.

Os filtros que geraram os diagramas temporais acima foram projetados utilizando


a mesma topologia da Fig. 13 e a equação 5, para alterar a frequência de corte,
mantendo o valor de capacitância fixo e alterando o valor de resistência.
O comportamento dos sinais ocorreu conforme esperado, quanto menor a
frequência de corte maior a atenuação do sinal e maior o desvio no valor da frequência
comparada a frequência do sinal de entrada. Esse comportamento justifica a escolha
anterior de uma frequência de corte abaixo do valor da entrada, já que a atenuação
esperada era de 4V e um pequeno desvio na frequência neste caso era aceitável.

GERADOR SENOIDAL TRIFÁSICO


Uma vez elaborado o gerador senoidal, torna-se possível a elaboração também
de um gerador senoidal trifásico, cuja saída são três senoides defasadas entre si por
120°. Nesse caso, foi necessária uma alteração no divisor de frequência de clock, que
passou a não somente reduzir a frequência de uma onda quadrada de 5 MHz, como
também gerar três sinais quadrados defasados (Fig.16).

Fig. 16 – Divisor de frequência e defasador do sinal de clock.


Considerando a combinação padrão S3 = S0 = S1 = ‘0’; S2 = ‘1’ , as formas de
onda originadas, considerando 50 pontos armazenados na memória ROM, podem ser
observadas na Fig.17.

12
Fig. 17 – Resposta do divisor de frequência e defasador do sinal de clock para S3 = S0 = S1 = ‘0’; S2 = ‘1’
(50 pontos).
A defasagem foi obtida através da adição de registradores de deslocamento no
sinal dividido, isto é, na resposta original do divisor da Fig.3. Ainda, a modificação pode
ser observada no script do Anexo IV. Graficamente, as senoides defasadas e filtradas
podem ser observadas na Fig.18.

Fig. 18 – Resposta do gerador senoidal para Vref = 15V, Amp = 12V (50 pontos).
Observa-se que a defasagem não é perfeita, de forma que os sinais não são
totalmente simétricos. Essa assimetria é consequência da utilização do registrador de
deslocamento, uma vez que, como a indexação do vetor de dados é feita por números
inteiros, não é possível um ajuste fino da defasagem.
Assim, ao somar as três componentes representadas na Fig.16, notou-se uma
tensão residual de cerca de 1V, o que caracteriza o gerador trifásico elaborado como
não balanceado.

13
ANEXO I – SCRIPT VHDL DO DIVISOR DE FREQUÊNCIA (25 PONTOS)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity clock_divider is
port(S3: in std_logic;
S2: in std_logic;
S1: in std_logic;
S0: in std_logic;
i_clk: in std_logic;
o_clk: out std_logic
);
end entity;

architecture rtl of clock_divider is

signal count: std_logic_vector(9 downto 0) := "0000000001";


signal limite: std_logic_vector(9 downto 0);
signal tmp: std_logic := '0';

begin
process(i_clk) begin
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '0') then
limite <= "0111110100";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '0') then


limite <= "0111111110";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "0111101010";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "0111100000";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "1000001000";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "1000001000";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "0111010110";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "0111001100";
end if;

14
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '1') then
limite <= "1000011100";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '1') then


limite <= "1000100110";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "0111000010";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "0110111000";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "1000110000";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "1000111010";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "0110101110";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "0110100100";
end if;

if (rising_edge(i_clk)) then
count <= count + 1;
if (count = limite) then
tmp <= not tmp;
count <= "0000000001";
end if;
end if;

o_clk <= tmp;


end process;
end architecture;

15
ANEXO II – SCRIPT VHDL DO DIVISOR DE FREQUÊNCIA (50 PONTOS)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity clock_divider is
port(S3: in std_logic;
S2: in std_logic;
S1: in std_logic;
S0: in std_logic;
i_clk: in std_logic;
o_clk: out std_logic
);
end entity;

architecture rtl of clock_divider is

signal count: std_logic_vector(8 downto 0) := "000000001";


signal limite: std_logic_vector(8 downto 0);
signal tmp: std_logic := '0';

begin
process(i_clk) begin
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '0') then
limite <= "011111010";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '0') then


limite <= "011111111";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "011110101";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "011110000";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "100000100";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "100000100";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "011101011";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "011100110";
end if;

16
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '1') then
limite <= "100001110";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '1') then


limite <= "100010011";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "011100001";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "011011100";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "100011000";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "100011101";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "011010111";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "011010010";
end if;

if (rising_edge(i_clk)) then
count <= count + 1;
if (count = limite) then
tmp <= not tmp;
count <= "000000001";
end if;
end if;

o_clk <= tmp;


end process;
end architecture;

17
ANEXO III – SCRIPT VHDL DO DIVISOR DE FREQUÊNCIA (100 PONTOS)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity clock_divider is
port(S3: in std_logic;
S2: in std_logic;
S1: in std_logic;
S0: in std_logic;
i_clk: in std_logic;
o_clk: out std_logic
);
end entity;

architecture rtl of clock_divider is

signal count: std_logic_vector(8 downto 0) := "000000001";


signal limite: std_logic_vector(8 downto 0);
signal tmp: std_logic := '0';

begin
process(i_clk) begin
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '0') then
limite <= "001111101";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '0') then


limite <= "001111111";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "001111010";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "001111000";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "010000010";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "010000010";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "001110101";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "001110011";
end if;

18
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '1') then
limite <= "010000111";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '1') then


limite <= "010001001";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "001110000";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "001101110";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "010001100";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "010001110";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "001101011";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "001101001";
end if;

if (rising_edge(i_clk)) then
count <= count + 1;
if (count = limite) then
tmp <= not tmp;
count <= "000000001";
end if;
end if;
o_clk <= tmp;
end process;
end architecture;

19
ANEXO IV – SCRIPT VHDL DO DIVISOR DE FREQUÊNCIA E DEFASADOR
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity phase_shifter is
port(S3: in std_logic;
S2: in std_logic;
S1: in std_logic;
S0: in std_logic;
i_clk: in std_logic;
o_clk: out std_logic;
o_clk2: out std_logic;
o_clk3: out std_logic
);
end entity;

architecture rtl of phase_shifter is

signal count: std_logic_vector(8 downto 0) := "000000001";


signal limite: std_logic_vector(8 downto 0);
signal tmp: std_logic := '0';

signal phase: std_logic_vector(80 downto 0) := (others => '0');

begin
process(i_clk) begin
if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '0') then
limite <= "011111010";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '0') then


limite <= "011111111";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "011110101";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '0') then


limite <= "011110000";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "100000100";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '0') then


limite <= "100000100";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '0') then


limite <= "011101011";
end if;

20
if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '0') then
limite <= "011100110";
end if;

if (S0 = '0' and S1 = '0' and S2 = '0' and S3 = '1') then


limite <= "100001110";
end if;

if (S0 = '1' and S1 = '0' and S2 = '0' and S3 = '1') then


limite <= "100010011";
end if;

if (S0 = '0' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "011100001";
end if;

if (S0 = '1' and S1 = '1' and S2 = '0' and S3 = '1') then


limite <= "011011100";
end if;

if (S0 = '0' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "100011000";
end if;

if (S0 = '1' and S1 = '0' and S2 = '1' and S3 = '1') then


limite <= "100011101";
end if;

if (S0 = '0' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "011010111";
end if;

if (S0 = '1' and S1 = '1' and S2 = '1' and S3 = '1') then


limite <= "011010010";
end if;

if (rising_edge(i_clk)) then
count <= count + 1;
if (count = limite) then
tmp <= not tmp;
phase(79 downto 0) <= phase(80 downto 1);
phase(80) <= tmp;
count <= "000000001";
end if;
end if;
o_clk <= tmp;
o_clk2 <= phase(50);
o_clk3 <= phase(14);
end process;
end architecture;

21
ANEXO V – SCRIPT VHDL DA MEMÓRIA ROM
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ROM_sen is

port(
addr : in std_logic_vector(7 downto 0);
D0: out std_logic;
D1: out std_logic;
D2: out std_logic;
D3: out std_logic;
D4: out std_logic;
D5: out std_logic;
D6: out std_logic;
D7: out std_logic
);
end entity;

architecture arch of ROM_sen is

type rom_type is array (0 to 100) of std_logic_vector(7 downto 0);


--100 equivale ao máximo de amostras a serem armazenadas. Quando o número de
--amostras é menor do que 100, os espaços vazios são preenchidos por "11111111",
--não sendo utilizados, pois o contador reinicia antes.

signal aux: std_logic_vector(7 downto 0);


signal sen_ROM : rom_type := (

" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
22
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",

23
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
);
begin
aux <= sen_ROM(to_integer(unsigned(addr)));
D0 <= aux(0);
D1 <= aux(1);
D2 <= aux(2);
D3 <= aux(3);
D4 <= aux(4);
D5 <= aux(5);
D6 <= aux(6);
D7 <= aux(7);

end architecture;

24
ANEXO VI – SCRIPT VHDL DO CONTADOR DE 8 BITS
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity counter_8 is

port (clk: in std_logic;


cout: out std_logic_vector (7 downto 0)
);
end entity;

architecture rtl of counter_8 is


signal count :std_logic_vector (7 downto 0) := "00000000";
begin
process (clk) begin
if (rising_edge(clk)) then
--O valor da igualdade depende do número de pontos na ROM (se 100, o contador
--reinicia em 99; se 51, reinicia em 50; se 25, reinicia em 24)
if count(7 downto 0) = " " then
count <= (others => '0');
else
count <= count + 1;
end if;
end if;
end process;
cout <= count;
end architecture;

25

Você também pode gostar