что не так с моей синусоидальной функцией VHDL? - PullRequest
4 голосов
/ 02 июня 2011
library IEEE;
use IEEE.MATH_REAL.ALL;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;

entity SineGen is
    Port (clock             : in  std_logic;
          dac_ab_vpp        : in  integer range 0 to 4095;
          dac_cd_vpp        : in  integer range 0 to 4095;
          sine_dac_ab       : out std_logic_vector(11 downto 0);
          sine_dac_cd       : out std_logic_vector(11 downto 0));
end SineGen;

architecture Behavioral of SineGen is

subtype slv is std_logic_vector(11 downto 0);


begin

        process(clock)
            variable count       : integer range 0 to 255  := 0;
            variable temp_dac_ab : integer range 0 to 4095 := 0;
            variable temp_dac_cd : integer range 0 to 4095 := 0;

        begin   
            if rising_edge(clock) then

Я перепробовал все, и все сводится к тому, что следующие две строки всегда выводят ноль , и я не понимаю почему. Это должен был быть выход с синусоидальной функцией. (количество - это 256 выборок за период. n - это количество битов.) Имеются ли следующие значения в допустимом формате?

                -- A*sin (2PI/2^n * count)
                temp_dac_ab := dac_ab_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));
                temp_dac_cd := dac_cd_vpp * integer(round(sin(real(count * integer(math_2_pi/real(256))))));

                if count < 256 then 
                    count := count + 1;
                else
                    count := 0;
                end if;

                sine_dac_ab <= conv_std_logic_vector(temp_dac_ab, slv'length); 
                sine_dac_cd <= conv_std_logic_vector(temp_dac_cd, slv'length); 

            end if;


        end process;
end Behavioral;

Ответы [ 2 ]

3 голосов
/ 02 июня 2011

В дополнение к тому, что было указано @brianreavis, вы не хотите преобразовывать дробь math_2_pi/real(256) в целое число, поскольку это всегда будет 0. Итак:

temp_dac_ab := integer(round(dac_ab_vpp * sin(real(count) * math_2_pi/real(256))));
temp_dac_cd := integer(round(dac_cd_vpp * sin(real(count) * math_2_pi/real(256))));
0 голосов
/ 02 июня 2011

Я действительно ржавый с моим VHDL, но я думаю, что вы хотите этого:

temp_dac_ab := integer(round(dac_ab_vpp * sin(real(count * integer(math_2_pi/real(256))))));
temp_dac_cd := integer(round(dac_cd_vpp * sin(real(count * integer(math_2_pi/real(256))))));

(Вы не хотите округлять / разыгрывать число с плавающей точкой, начиная с sin, пока вы не умножите его на dac_ab_vpp / dac_cd_vpp)

...