From d28518a13ea3ba14982d8c7dc755d970f0b0b88f Mon Sep 17 00:00:00 2001 From: T-moe Date: Tue, 17 May 2016 12:25:10 +0200 Subject: [PATCH] Finalized first version of dds. --- dds.vhd | 56 ++++++++++++++++++++++++++++++++---------------------- dds_tb.vhd | 51 +++++++++++++++++++++++++------------------------ yasg.gise | 15 +++++++++------ 3 files changed, 68 insertions(+), 54 deletions(-) diff --git a/dds.vhd b/dds.vhd index cba5adf..7cae0f1 100644 --- a/dds.vhd +++ b/dds.vhd @@ -20,11 +20,7 @@ library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; - --- Uncomment the following library declaration if instantiating --- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; +use IEEE.MATH_REAL.ALL; use work.helpers.all; entity dds is @@ -36,38 +32,52 @@ entity dds is Port ( clk : in STD_LOGIC; freq : in unsigned (log2_int(max_freq)-1 downto 0); form : in unsigned (1 downto 0); - amp : out signed (adc_res-1 downto 0); - update : out STD_LOGIC); + amp : out unsigned (adc_res-1 downto 0)); end dds; architecture Behavioral of dds is signal m, idx : unsigned(acc_res -1 downto 0):= (others => '0'); signal idx_phase : unsigned(phase_res-1 downto 0) := (others => '0'); - signal amp_rect, amp_saw, amp_tria, amp_sin : signed (adc_res-1 downto 0); + signal amp_rect, amp_saw, amp_tria, amp_sin : unsigned (adc_res-1 downto 0); + + type storage is array (((2**phase_res)/4)-1 downto 0) of unsigned (adc_res-2 downto 0); + function gen_sin_wave return storage is + variable temp : storage; + begin + forLoop: for i in 0 to temp'high loop + temp(i) := to_unsigned(integer(real((2**(adc_res-1))-1)*sin((real(i)*MATH_PI/2.0)/real(temp'high))),adc_res-1); + end loop; + return temp; + end function gen_sin_wave; + constant sin_wave : storage := gen_sin_wave; begin - -- m = f0*2^n/fc + + -- m = fout*(2^n)/fclk m <= resize(divide(shift_left(resize(freq,64),acc_res),to_unsigned(clk_freq,64)),m'length); idx_phase <= idx(acc_res -1 downto acc_res - phase_res); - amp_rect <= to_signed((2**(adc_res-1)) - 1,adc_res) when idx_phase(phase_res-1)='0' else - to_signed(-(2**(adc_res-1)),adc_res); + amp_rect <= to_unsigned(0,adc_res) when idx_phase(phase_res-1)='0' else + to_unsigned((2**adc_res)-1,adc_res); - amp_saw <= to_signed(-(2**(adc_res-1)),adc_res) - + signed(resize(unsigned(((2**adc_res) -1)*idx_phase/2**phase_res),adc_res)) ; + amp_saw <= resize(unsigned(((2**adc_res) -1)*idx_phase/2**phase_res),adc_res) ; - amp_tria <= to_signed(-(2**(adc_res-1)),adc_res) - + signed(resize(unsigned(((2**adc_res) -1)*idx_phase/2**(phase_res-1)),adc_res)) + amp_tria <= resize(unsigned(((2**adc_res) -1)*idx_phase/2**(phase_res-1)),adc_res) when idx_phase(phase_res-1)='0' else - resize(to_signed((2**(adc_res))-1,adc_res+1) - - signed(resize(unsigned(((2**adc_res) -1)*idx_phase/2**(phase_res-1)),adc_res)),adc_res); + resize(unsigned((2**(adc_res+1)) - ((2**adc_res) -1)*idx_phase/2**(phase_res-1)),adc_res); - - - amp <= amp_tria; - - - + -- Modulo is only required to prevent a synthesizer warning, but the value is actually never > 2**phase_res/4 + amp_sin <= to_unsigned((2**(adc_res-1)) - 1,adc_res) + sin_wave(to_integer(idx_phase) mod ((2**phase_res)/4)) when idx_phase(phase_res-1 downto phase_res-2)="00" else + to_unsigned((2**(adc_res-1)) - 1,adc_res) + sin_wave(to_integer(((2**phase_res)/2)-idx_phase) mod ((2**phase_res)/4)) when idx_phase(phase_res-1 downto phase_res-2)="01" else + to_unsigned((2**(adc_res-1)) - 1,adc_res) - sin_wave(to_integer(idx_phase-((2**phase_res)/2)) mod ((2**phase_res)/4)) when idx_phase(phase_res-1 downto phase_res-2)="10" else + to_unsigned((2**(adc_res-1)) - 1,adc_res) - sin_wave(to_integer(((2**phase_res)-1)-idx_phase) mod ((2**phase_res)/4)); + + with form select amp <= amp_rect when "00", + amp_saw when "01", + amp_tria when "10", + amp_sin when others; + + P1: process(clk) begin if(rising_edge(clk)) then diff --git a/dds_tb.vhd b/dds_tb.vhd index 31fed4e..73b1259 100644 --- a/dds_tb.vhd +++ b/dds_tb.vhd @@ -41,8 +41,7 @@ ARCHITECTURE behavior OF dds_tb IS clk : IN std_logic; freq : IN unsigned(16 downto 0); form : IN unsigned(1 downto 0); - amp : OUT signed(11 downto 0); - update : OUT std_logic + amp : OUT unsigned(11 downto 0) ); END COMPONENT; @@ -53,8 +52,7 @@ ARCHITECTURE behavior OF dds_tb IS signal form : unsigned(1 downto 0) := (others => '0'); --Outputs - signal amp : signed(11 downto 0); - signal update : std_logic; + signal amp : unsigned(11 downto 0); -- Clock period definitions constant clk_period : time := 20 ns; --50mhz @@ -66,8 +64,7 @@ BEGIN clk => clk, freq => freq, form => form, - amp => amp, - update => update + amp => amp ); -- Clock process definitions @@ -87,27 +84,31 @@ BEGIN wait for 100 ns; - freq <= to_unsigned(100000,17); - wait for 2000 ms; - - freq <= to_unsigned(10,17); - wait for 200 ms; - - freq <= to_unsigned(100,17); - wait for 20 ms; - - freq <= to_unsigned(1000,17); - wait for 2 ms; - - freq <= to_unsigned(10000,17); - wait for 1 ms; - + + form <= "00"; freq <= to_unsigned(50000,17); - wait for 1 ms; - + wait for 40 us; freq <= to_unsigned(100000,17); - wait for 1 ms; - -- insert stimulus here + wait for 20 us; + + form <= "01"; + freq <= to_unsigned(50000,17); + wait for 40 us; + freq <= to_unsigned(100000,17); + wait for 20 us; + + form <= "10"; + freq <= to_unsigned(50000,17); + wait for 40 us; + freq <= to_unsigned(100000,17); + wait for 20 us; + + form <= "11"; + freq <= to_unsigned(50000,17); + wait for 40 us; + freq <= to_unsigned(100000,17); + wait for 20 us; + wait; end process; diff --git a/yasg.gise b/yasg.gise index 6799a8a..b11f790 100644 --- a/yasg.gise +++ b/yasg.gise @@ -60,7 +60,7 @@ - + @@ -80,7 +80,7 @@ - + @@ -88,9 +88,11 @@ - + + + @@ -98,9 +100,11 @@ - + + + @@ -133,9 +137,8 @@ - + -