aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFriedrich Beckmann <friedrich.beckmann@hs-augsburg.de>2023-03-15 22:30:08 +0100
committerFriedrich Beckmann <friedrich.beckmann@hs-augsburg.de>2023-03-15 22:30:08 +0100
commitdf418208aa0570a99f6ab6657d54ee65d6162168 (patch)
treec68b3f968866e978852eed508a5605e914be3951 /src
parent0ace43acf8c1953289ae9ae3756d9f10949f060e (diff)
added de1_sine sinewave generator for ADC/DAC board
I added a sinewave generator based on DDS in VHDL to generate a sinewave with the ADC/DAC board. This can be used to demonstrate the Aliasing Lowpass filter.
Diffstat (limited to 'src')
-rw-r--r--src/de1_sine.vhd99
-rw-r--r--src/sine_rtl.vhd56
-rw-r--r--src/t_de1_sine.vhd80
3 files changed, 235 insertions, 0 deletions
diff --git a/src/de1_sine.vhd b/src/de1_sine.vhd
new file mode 100644
index 0000000..d3073f2
--- /dev/null
+++ b/src/de1_sine.vhd
@@ -0,0 +1,99 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity de1_sine is
+ port (
+ CLOCK_50 : in std_ulogic;
+ KEY0 : in std_ulogic;
+ SW : in std_ulogic_vector(9 downto 0);
+ DAC_MODE : out std_ulogic;
+ DAC_WRT_A : out std_ulogic;
+ DAC_WRT_B : out std_ulogic;
+ DAC_CLK_A : out std_ulogic;
+ DAC_CLK_B : out std_ulogic;
+ DAC_DA : out std_ulogic_vector(13 downto 0);
+ DAC_DB : out std_ulogic_vector(13 downto 0);
+ POWER_ON : out std_ulogic;
+ ADC_CLK_A : out std_ulogic;
+ ADC_CLK_B : out std_ulogic;
+ ADC_OEB_A : out std_ulogic;
+ ADC_OEB_B : out std_ulogic;
+ LEDR : out std_ulogic_vector(9 downto 0));
+end de1_sine;
+
+architecture rtl of de1_sine is
+
+ component sine is
+ port (
+ clk : in std_ulogic;
+ rst_n : in std_ulogic;
+ phase_inc_i : in std_ulogic_vector(9 downto 0);
+ phase_o : out std_ulogic_vector(9 downto 0);
+ sample_o : out std_ulogic_vector(13 downto 0));
+ end component sine;
+
+ -- component ports
+ signal clk : std_ulogic;
+ signal rst_n : std_ulogic;
+ signal phase_inc_reg : std_ulogic_vector(9 downto 0);
+ signal sample : std_ulogic_vector(13 downto 0);
+ signal daca_reg1, daca_reg2 : std_ulogic_vector(13 downto 0);
+ signal dacb_reg1, dacb_reg2 : std_ulogic_vector(13 downto 0);
+ signal phase : std_ulogic_vector(9 downto 0);
+
+begin
+
+ phase_inc_reg <= "0000000000" when rst_n = '0' else SW when rising_edge(clk);
+
+ sinegen : sine
+ port map (
+ clk => clk,
+ rst_n => rst_n,
+ phase_inc_i => phase_inc_reg,
+ phase_o => phase,
+ sample_o => sample);
+
+ -- clock and reset signal
+ clk <= CLOCK_50;
+ rst_n <= KEY0;
+
+ LEDR <= SW;
+
+ -- DAC in dual-port mode
+ DAC_MODE <= '1';
+ DAC_WRT_A <= clk;
+ DAC_WRT_B <= clk;
+ DAC_CLK_A <= clk;
+ DAC_CLK_B <= clk;
+
+ -- Register to sinegen outputs to relax timing
+ daca_reg1 <= sample when rising_edge(clk);
+ daca_reg2 <= daca_reg1 when rising_edge(clk);
+ dacb_reg1 <= phase & "0000" when rising_edge(clk);
+ dacb_reg2 <= dacb_reg1 when rising_edge(clk);
+
+ -- DAC on board has 00000000000000 as minimum value
+ -- and 11111111111111 as maximum value
+ -- therefore the conversion has to look like this
+ -- input signed value output DAC value
+ -- minimum 10000000000000 00000000000000
+ -- zero 00000000000000 10000000000000
+ -- maximum 01111111111111 11111111111111
+
+ -- assign to DAC channels
+ DAC_DA <= "10000000000000" WHEN rst_n = '0' ELSE
+ (NOT(daca_reg2(13)) & daca_reg2(12 downto 0)) WHEN falling_edge(clk);
+ DAC_DB <= "10000000000000" when rst_n = '0' else
+ dacb_reg2 when falling_edge(clk);
+
+ -- ADC section all off!
+ ADC_CLK_A <= '0';
+ ADC_CLK_B <= '0';
+ ADC_OEB_A <= '0';
+ ADC_OEB_B <= '0';
+
+ -- switch on DAC/ADC
+ POWER_ON <= '1';
+
+end architecture;
diff --git a/src/sine_rtl.vhd b/src/sine_rtl.vhd
new file mode 100644
index 0000000..4bc9dd2
--- /dev/null
+++ b/src/sine_rtl.vhd
@@ -0,0 +1,56 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+entity sine is
+ port (clk : in std_ulogic;
+ rst_n : in std_ulogic;
+ phase_inc_i : in std_ulogic_vector(9 downto 0);
+ phase_o : out std_ulogic_vector(9 downto 0);
+ sample_o : out std_ulogic_vector(13 downto 0));
+end entity;
+
+architecture rtl of sine is
+
+ signal phase : unsigned(9 downto 0);
+
+ type rom_t is array (0 to 1023) of signed(13 downto 0);
+
+ function sine_rom_init_f return rom_t is
+ variable phase_real : real := 0.0;
+ variable sinereal : real;
+ variable sinequan : signed(13 downto 0);
+ variable rom_v : rom_t;
+ begin
+ for i in 0 to 1023 loop
+ phase_real := 2.0 * MATH_PI * real(i) / 1024.0;
+ sinereal := sin(phase_real);
+ sinequan := to_signed(integer(sinereal * real(2**13-1)), 14);
+ rom_v (i) := sinequan;
+ end loop;
+ return rom_v;
+ end function;
+
+ constant rom : rom_t := sine_rom_init_f;
+
+ signal rom_out_reg : signed(13 downto 0);
+ signal rom_index_reg : integer range 0 to 1023;
+
+begin
+
+ -- phase accumulator
+ phase <= "0000000000" when rst_n = '0' else
+ phase + unsigned(phase_inc_i) when rising_edge(clk);
+
+ rom_index_reg <= to_integer(phase) when rising_edge(clk);
+
+ rom_out_reg <= rom(rom_index_reg) when rising_edge(clk);
+
+ sample_o <= "00000000000000" when rst_n = '0' else
+ std_ulogic_vector(rom_out_reg) when rising_edge(clk);
+
+ phase_o <= "0000000000" when rst_n = '0' else
+ std_ulogic_vector(phase) when rising_edge(clk);
+
+end architecture rtl;
diff --git a/src/t_de1_sine.vhd b/src/t_de1_sine.vhd
new file mode 100644
index 0000000..67b81ae
--- /dev/null
+++ b/src/t_de1_sine.vhd
@@ -0,0 +1,80 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity t_de1_sine is
+end entity;
+
+architecture beh of t_de1_sine is
+
+component de1_sine is
+ port (
+ CLOCK_50 : in std_ulogic;
+ KEY0 : in std_ulogic;
+ SW : in std_ulogic_vector(9 downto 0);
+ DAC_MODE : out std_ulogic;
+ DAC_WRT_A : out std_ulogic;
+ DAC_WRT_B : out std_ulogic;
+ DAC_CLK_A : out std_ulogic;
+ DAC_CLK_B : out std_ulogic;
+ DAC_DA : out std_ulogic_vector(13 downto 0);
+ DAC_DB : out std_ulogic_vector(13 downto 0);
+ POWER_ON : out std_ulogic;
+ ADC_CLK_A : out std_ulogic;
+ ADC_CLK_B : out std_ulogic;
+ ADC_OEB_A : out std_ulogic;
+ ADC_OEB_B : out std_ulogic;
+ LEDR : out std_ulogic_vector(9 downto 0));
+end component;
+
+ signal clk : std_ulogic;
+ signal rst_n : std_ulogic;
+
+ signal dac_mode, dac_wrt_a, dac_wrt_b, dac_clk_a,
+ dac_clk_b, power_on, adc_clk_a, adc_clk_b,
+ adc_oeb_a, adc_oeb_b : std_ulogic;
+ signal dac_da, dac_db : std_ulogic_vector(13 downto 0);
+ signal ledr, sw : std_ulogic_vector(9 downto 0);
+
+ signal simstop : boolean;
+
+begin
+
+ dut : de1_sine
+ port map(
+ CLOCK_50 => clk,
+ KEY0 => rst_n,
+ SW => sw,
+ DAC_MODE => dac_mode,
+ DAC_WRT_A => dac_wrt_a,
+ DAC_WRT_B => dac_wrt_b,
+ DAC_CLK_A => dac_clk_a,
+ DAC_CLK_B => dac_clk_b,
+ DAC_DA => dac_da,
+ DAC_DB => dac_db,
+ POWER_ON => power_on,
+ ADC_CLK_A => adc_clk_a,
+ ADC_CLK_B => adc_clk_b,
+ ADC_OEB_A => adc_oeb_a,
+ ADC_OEB_B => adc_oeb_b,
+ LEDR => ledr
+ );
+
+ clk_p : process
+ begin
+ clk <= '0';
+ wait for 10 ns;
+ clk <= '1';
+ wait for 10 ns;
+ if simstop then
+ wait;
+ end if;
+ end process;
+
+ rst_n <= '0', '1' after 50 ns;
+
+ simstop <= false, true after 30 us;
+
+ sw <= "0000000001";
+
+end architecture; \ No newline at end of file