Vous êtes sur la page 1sur 7

http://www.ciudadoscura.com/electronica/1/gener ador-de-senal-sinusoidal-en-vhdl.

html Generador de seal sinusoidal en VHDL


Es posible que se necesite generar algn tipo de seal mediante VHDL y una FPGA. Sabemos que comnmente, una FPGA solo genera seales de tipo lgico, es decir, estado alto y bajo. Es posible obtener una seal ms all de esos dos estados usando un convertidor digital-anlogo R-2R cuyo funcionamiento se describe en el siguiente video.

En ste caso tendremos un nmero de 8 bits (1 byte). Utilizando un pequeo programa en Matlab nos es posible obtener valores dividiendo 1 periodo de la funcin seno entre el nmero de muestras que deseemos. A razn de que tenemos 8 bits, nuestro mximo valor en decimal es 255 y el mnimo 0. 11111111(2) 00000000(2) = = 255(10) 0(10)

A continuacin, sabiendo todo lo anterior, pasamos a calcular los valores decimales para 25 muestras en este caso.

clc clear frec = 10^6; t = 0:(1/frec)/25:(1/frec); y = (255/2)*(sin(2*pi*frec*t)+1); plot(t,y,'-k*','LineWidth',1,'MarkerEdgeColor','b') hold on axis([0 (1/frec) 0 255]) for n = 0:24 xl = [(n*((1/frec)/25)) (n*((1/frec)/25))]; yl = [0 255]; line(xl,yl); (255/2)*(sin(2*pi*frec*(n*((1/frec)/25)))+1) end

Ahora, en la consola de Matlab tendremos 25 valores decimales pero necesitamos que sean enteros para poder usar los 8 bits, entonces aproximamos los valores a su nmero entero ms cercano. Luego de esto, pasamos a convertir cada nmero de decimal a binario y ya tendremos nuestra tabla de 25 valores. Teniendo la tabla solo nos queda describir el funcionamiento del generador con VHDL. A continuacin un ejemplo.

--------------------------------------The Dark City --www.ciudadoscura.com --Camilo Rojas G. ------------------------------------library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity gen is port ( clk : in STD_LOGIC; reset : in STD_LOGIC; seno : out STD_LOGIC_VECTOR(7 downto 0));

end gen; architecture Behavioral of gen is signal contador: natural; begin --Tabla de la seal sinusoidal con 25 muestras. process(contador) begin case(contador) is when 0 => seno <= "01111111"; when 1 => seno <= "10011111"; when 2 => seno <= "10111101"; when 3 => seno <= "11010111"; when 4 => seno <= "11101011"; when 5 => seno <= "11111001"; when 6 => seno <= "11111111"; when 7 => seno <= "11111101"; when 8 => seno <= "11110011"; when 9 => seno <= "11100010"; when 10 => seno <= "11001010"; when 11 => seno <= "10101110"; when 12 => seno <= "10001111"; when 13 => seno <= "01110000"; when 14 => seno <= "01010001"; when 15 => seno <= "00110101"; when 16 => seno <= "00011101"; when 17 => seno <= "00001100"; when 18 => seno <= "00000010"; when 19 => seno <= "00000000"; when 20 => seno <= "00000110"; when 21 => seno <= "00010100"; when 22 => seno <= "00101000"; when 23 => seno <= "01000010"; when 24 => seno <= "01100000"; when others => seno<="00000000"; end case; end process; process(clk, reset) begin if(reset = '1') then contador <= 0; elsif(clk'event and clk='1') then if(contador = 24) then contador <= 0; else contador <= contador + 1; end if; end if; end process; end Behavioral;

Ahora solo queda definir nuestros pines de salida de

seno (de 8 bits) y nuestro reloj clk.

Recuerda que la frecuencia de la seal ser dada por la frecuencia del reloj dividida por el nmero de muestras que tomamos (25). Fuentes: Stephen Brown, Zvonko Vranesic. Fundamentos de lgica digital con diseo VHDL. Segunda edicin.

McGraw-Hill. Autor: Camilo R. Rojas G.

2006.

OTRA FORMA
http://www.doulos.com/knowhow/vhdl_designers_guide/models/sine_wave_generator/
Synthesisable generador de onda sinusoidal Esta pgina le ofrece un generador de onda sinusoidal personalizable. A continuacin se muestra una descripcin genrica VHDL de un generador de onda sinusoidal. Se parametriza mediante constantes y subtipos declarados en sine_package. Ms abajo es un formulario HTML para que especifique la palabra y tamaos de direcciones para una tabla para almacenar los valores de una onda sinusoidal. Enve el formulario y un script cortos en Perl se ejecuta en el servidor para generar un personalizado sine_package completa con tabla de bsqueda para usted. Esta aplicacin es moderadamente eficiente de la memoria, ya que almacena slo el primer pi / 2 radianes de valores de seno. El segundo pi / 2 radianes es una imagen especular de la primera en el tiempo y el segundo pi radianes es una imagen de espejo en la amplitud de las primera Pi radianes. Memoria podra ser salvado si los incrementos se registraron en lugar de cada valor absoluto. Se necesitan menos bits por valor, sin embargo, sera necesario hardware adicional para una vbora.

CODIGO:
-- Synthesisable design for a sine wave generator -- Copyright Doulos Ltd -- SD, 07 Aug 2003

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.sine_package.all;

entity sine_wave is port( clock, reset, enable: in std_logic; wave_out: out sine_vector_type); end;

architecture arch1 of sine_wave is type state_type is ( counting_up, change_down, counting_down, change_up ); signal state, next_state: state_type; signal table_index: table_index_type; signal positive_cycle: boolean; begin

process( clock, reset ) begin if reset = '1' then state <= counting_up; elsif rising_edge( clock ) then if enable = '1' then state <= next_state; end if; end if; end process;

process( state, table_index ) begin next_state <= state; case state is when counting_up => if table_index = max_table_index then next_state <= change_down; end if; when change_down => next_state <= counting_down; when counting_down => if table_index = 0 then next_state <= change_up; end if; when others => -- change_up

next_state <= counting_up; end case; end process;

process( clock, reset ) begin if reset = '1' then table_index <= 0; positive_cycle <= true; elsif rising_edge( clock ) then if enable = '1' then case next_state is when counting_up => table_index <= table_index + 1; when counting_down => table_index <= table_index - 1; when change_up => positive_cycle <= not positive_cycle; when others => -- nothing to do end case; end if; end if; end process;

process( table_index, positive_cycle ) variable table_value: table_value_type; begin table_value := get_table_value( table_index ); if positive_cycle then wave_out <= std_logic_vector(to_signed(table_value,sine_vector_type'length)); else

wave_out <= std_logic_vector(to_signed(table_value,sine_vector_type'length)); end if; end process;

end;

Lookup Table
We will use a short Perl script to generate a lookup table in a package, sine_package. Specify a word size and address size suitable for your application. Values of 8 and 7 will generate a ROM of size 256 bytes.

Tabla de bsqueda Vamos a utilizar un script cortos en Perl para generar una tabla de bsqueda en un paquete, sine_package. Especifique un tamao de palabra y tamao de la direccin adecuada para su aplicacin. Los valores de 8 y 7 generarn una ROM de tamao de 256 bytes.
7
Lookup table word size

7
Lookup table address size

Generate sine_package Code

Test Bench
Download an example sine wave generator with a test bench: sine_testbench.zip

We have bundled a simple testbench to show how this code works. There's also a Tcl script called go.tcl to drive ModelSim for you. Here's what the output looks like in ModelSim.

Descargue un ejemplo del generador de onda sinusoidal con un banco de pruebas: sine_testbench.zip Hemos incluido un sencillo banco de pruebas para mostrar cmo funciona este cdigo. Tambin hay un script Tcl llamada go.tcl conducir ModelSim para usted. Esto es lo que la salida se ve como en ModelSim.

Synthesis
Both Synplicity's Synplify and Mentor's Leonardo Spectrum recognised the case statement in function get_table_value as a ROM.

Tanto de Synplicity Synplify y de Mentor Leonardo Spectrum reconocieron la declaracin de caso en funcin get_table_value como una ROM.