Ironlord
Member level 3
I want to implement a triangular wave in an FPGA. Values should go from -2047 to 2047, so I'm using a 12-bit precission.
The problem is that I want it to be variable in frequency, I want ot be able to modify it's input in order to generate different frequencies, like if it were a signal generator.
I hav developed the following code:
The problem I found is I think I am doing something wrong, guess it won't be precisse at all.
I was wondering if using a double precission or floating point would be a good choice or if it will make my system totally inneficient.
I am glad to hear some ideas which could help me to develop a better version of my code.
Thanks as always.
Cheers.
The problem is that I want it to be variable in frequency, I want ot be able to modify it's input in order to generate different frequencies, like if it were a signal generator.
I hav developed the following code:
Code:
library ieee;
use ieee.std_logic_1164.all;
--use ieee.std_logic_arith.all;
USE ieee.NUMERIC_STD.all;
use IEEE.std_logic_signed.all;
--Precondition: Frequencies goes in Hz.
entity triangle_gen is
port(
clk : in std_logic;
freqSmp : in std_logic_vector(25 downto 0); --Max freq could be 50Mhz
freqOut : in std_logic_vector(25 downto 0); --Output max frequency is the half the sample freq. (Nyquist)
triWave : out std_logic_vector(11 downto 0)
);
end triangle_gen;
Architecture a of triangle_gen is
--Senales
constant clk_freq : std_logic_vector(25 downto 0) :="10111110101111000010000000"; --defined as 50MHz
constant min_val : signed(11 downto 0) :="100000000001";
constant max_val : signed(11 downto 0) :="011111111111";
constant pp_max : std_logic_vector(11 downto 0) :="111111111111"; --Peak to peak
signal increment : std_logic_vector(11 downto 0) :=(others => '0'); --How much should I increment every time I stop?
signal half_cycle : std_logic_vector(11 downto 0) :=(others => '0');
signal cyc_count : std_logic_vector(25 downto 0) :=(others => '0'); --When do I stop to assign a value?
signal this_cycle: std_logic_vector(25 downto 0) :=(others => '0'); --How many clk cycles must I wait?
signal part_count: std_logic_vector(11 downto 0) :=(others => '0');
signal triWave_aux : std_logic_vector(11 downto 0) :="100000000001"; --Min_val. I start from the lowest.
signal remain : integer range -2047 to 4094 :=4094;
signal riseUp : std_logic :='1';
Begin
--Divisions should be made in the HPS (ARM) It's a SoC.
--cyc_count<=(clk_freq/freqSmp)-1;
--cyc_count<="00010011000100101100111111"; --Lo estoy poniendo a 5MHZ, como si quisiera hacerla de 1Hz con 10Hz de sampleo
cyc_count<="00000000000010011100010000"; --Lo estoy poniendo a 10KHZ, quiero hacer el sampleo a 5khz y la señal a 500hz.
half_cycle<=('0'& freqSmp(11 downto 1));
--increment<=(pp_max/half_cycle);
increment<="000000000010";--El increment es de 1.6384 en realidad
process(clk)
begin
if(rising_edge(clk))then
if(this_cycle<cyc_count)then --this_cycle signal acts like a trigger.
this_cycle<=this_cycle+'1';
else
if(riseUp='1')then
if(remain>(to_integer(signed(increment))))then
remain<=(remain-(to_integer(signed(increment))));
triWave_aux<=triWave_aux+increment;
else
triWave_aux<=std_logic_vector(max_val)-(increment-(std_logic_vector(to_signed(remain,12)))); --El remain es negativo, por lo tanto, la suma resta.
riseUp<='0';
remain<=(4094-(to_integer(signed(increment))))+remain;
end if;
else
if(remain>(to_integer(signed(increment))))then
remain<=(remain-(to_integer(signed(increment))));
triWave_aux<=triWave_aux-(std_logic_vector(signed(increment)));
else
triWave_aux<=std_logic_vector(min_val)+(increment-(std_logic_vector(to_signed(remain,12)))); --El remain es negativo, la resta suma.
riseUp<='1';
remain<=(4094-(to_integer(signed(increment))))+remain;
end if;
end if;
this_cycle<= (others => '0');
end if;
end if;
end process;
triWave<=triWave_aux;
end a;
The problem I found is I think I am doing something wrong, guess it won't be precisse at all.
I was wondering if using a double precission or floating point would be a good choice or if it will make my system totally inneficient.
I am glad to hear some ideas which could help me to develop a better version of my code.
Thanks as always.
Cheers.