414 lines
16 KiB
VHDL
414 lines
16 KiB
VHDL
--------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer:
|
|
--
|
|
-- Create Date: 16:53:22 03/24/2017
|
|
-- Design Name:
|
|
-- Module Name:
|
|
-- Project Name: xem7350
|
|
-- Target Device:
|
|
-- Tool versions:
|
|
-- Description:
|
|
--
|
|
-- VHDL Test Bench Created by ISE for module: dac_interface
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
-- Notes:
|
|
-- This testbench has been automatically generated using types std_logic and
|
|
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
|
|
-- that these types always be used for the top-level I/O of a design in order
|
|
-- to guarantee that the testbench will bind correctly to the post-implementation
|
|
-- simulation model.
|
|
--------------------------------------------------------------------------------
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.ALL;
|
|
USE IEEE.STD_LOGIC_arith.ALL;
|
|
USE IEEE.STD_LOGIC_unsigned.ALL;
|
|
|
|
-- Uncomment the following library declaration if using
|
|
-- arithmetic functions with Signed or Unsigned values
|
|
--USE ieee.numeric_std.ALL;
|
|
|
|
Library xpm;
|
|
use xpm.vcomponents.all;
|
|
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity dds_wrapper_tb is
|
|
end dds_wrapper_tb;
|
|
|
|
architecture behavior of dds_wrapper_tb is
|
|
|
|
-- Clock period definitions
|
|
constant CLK_125_PERIOD : time := 8 ns; -- 125 MHz
|
|
constant CLK_250_PERIOD : time := 4 ns; -- 250 MHz
|
|
constant CLK_100_PERIOD : time := 10 ns; -- 100 MHz
|
|
constant S_AXI_ACLK_PERIOD : time := 10 ns; -- 100 MHz
|
|
constant M_AXI_ACLK_PERIOD : time := 4 ns; -- 250 MHz 2.58 ns; -- 387 MHz
|
|
constant QSFP4_AXIS_ACLK_PERIOD : time := 5.12 ns; -- 195.310 MHz 5.12 ns;
|
|
constant QSFP1_AXIS_ACLK_PERIOD : time := 5.12 ns; -- 195.310 MHz 5.12 ns;
|
|
constant CLK_375_PERIOD : time := 2.667 ns; -- 375 MHz
|
|
|
|
signal clk_100 : std_logic := '0';
|
|
signal clk_100_aresetn : std_logic_vector(0 to 15) := (others => '0');
|
|
signal clk_250 : std_logic := '0';
|
|
signal clk_250_aresetn : std_logic_vector(0 to 63) := x"0000_FFFF_0000_0000";--(others => '0');
|
|
signal clk_375 : std_logic := '0';
|
|
signal clk_375_aresetn : std_logic_vector(0 to 63) := x"0000_FFFF_0000_0000";--(others => '0');
|
|
|
|
signal m0_dds_intfc_tdata_0 : std_logic_vector(31 downto 0);
|
|
signal m0_dds_intfc_tvalid_0 : std_logic;
|
|
|
|
signal m0_dds_intfc_tdata_1 : std_logic_vector(31 downto 0);
|
|
signal m0_dds_intfc_tvalid_1 : std_logic;
|
|
|
|
signal m0_dds_intfc_tdata_2 : std_logic_vector(31 downto 0);
|
|
signal m0_dds_intfc_tvalid_2 : std_logic;
|
|
|
|
signal m0_dds_intfc_tdata_3 : std_logic_vector(31 downto 0);
|
|
signal m0_dds_intfc_tvalid_3 : std_logic;
|
|
|
|
signal cmd_send_i : std_logic_vector(0 to 3) := (others => '0');
|
|
signal dac_holdoff_r : std_logic := '0';
|
|
|
|
signal chan0_i : std_logic_vector(15 downto 0);
|
|
signal chan0_q : std_logic_vector(15 downto 0);
|
|
signal chan1_i : std_logic_vector(15 downto 0);
|
|
signal chan1_q : std_logic_vector(15 downto 0);
|
|
signal chan2_i : std_logic_vector(15 downto 0);
|
|
signal chan2_q : std_logic_vector(15 downto 0);
|
|
signal chan3_i : std_logic_vector(15 downto 0);
|
|
signal chan3_q : std_logic_vector(15 downto 0);
|
|
|
|
signal cmd_send_0_r : std_logic_vector(0 to 2) := (others => '0');
|
|
signal cmd_send_1_r : std_logic_vector(0 to 2) := (others => '0');
|
|
signal cmd_send_2_r : std_logic_vector(0 to 2) := (others => '0');
|
|
signal cmd_send_3_r : std_logic_vector(0 to 2) := (others => '0');
|
|
signal cnt_reset : std_logic := '0';
|
|
|
|
signal dac_r : std_logic_vector(15 downto 0) := (others => '0');
|
|
signal dac_i : std_logic_vector(15 downto 0);
|
|
signal dac_idx_r : std_logic_vector(1 downto 0) := (others => '0');
|
|
|
|
begin
|
|
|
|
clk_100 <= not clk_100 after CLK_100_PERIOD/2;
|
|
clk_375 <= not clk_375 after CLK_375_PERIOD/2;
|
|
|
|
--
|
|
process(clk_100)
|
|
begin
|
|
if (rising_edge(clk_100)) then
|
|
clk_100_aresetn <= clk_100_aresetn(1 to 15) & '1';
|
|
end if;
|
|
end process;
|
|
|
|
--
|
|
process(clk_375)
|
|
begin
|
|
if (rising_edge(clk_375)) then
|
|
clk_375_aresetn <= clk_375_aresetn(1 to 63) & '1';
|
|
end if;
|
|
end process;
|
|
|
|
process (clk_100)
|
|
begin
|
|
if rising_edge(clk_100) then
|
|
if (cmd_send_i(0) = '1') then
|
|
cmd_send_0_r <= "111";
|
|
else
|
|
cmd_send_0_r <= cmd_send_0_r(1 to 2) & '0';
|
|
end if;
|
|
|
|
if (cmd_send_i(1) = '1') then
|
|
cmd_send_1_r <= "111";
|
|
else
|
|
cmd_send_1_r <= cmd_send_1_r(1 to 2) & '0';
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
-- Fs_dds = 375 MHz
|
|
-- Number_of_cores = 4
|
|
-- Fs_effective = 4 * 375 MHz = 1.5 GHz
|
|
-- Fstart = 1 MHz
|
|
-- Phase inc width = 32
|
|
-- start_phase_inc = Fout / Fs_dds * 2^PhaseIncWidth
|
|
-- = 11,453,246
|
|
-- = 0x00AEC33E
|
|
----
|
|
-- Fstop = 101 MHz
|
|
-- end_phase_inc = Fstart / Fs_dds * 2^PhaseWidth
|
|
-- = 1,156,777,858.39
|
|
-- = 0x44F30782
|
|
|
|
--Since there are 4 interleaved DDS cores, the phase offset step is:
|
|
-- phase_offset_step = start_phase_inc / Number_of_cores
|
|
-- = 0x00AEC33E / 4
|
|
-- = 0x002BB0D0
|
|
|
|
--PHASE_OFFSET_DDS0 = 0 * phase_offset_step = 0x00000000
|
|
--PHASE_OFFSET_DDS1 = 1 * phase_offset_step = 0x002BB0D0
|
|
--PHASE_OFFSET_DDS2 = 2 * phase_offset_step = 0x0057619F
|
|
--PHASE_OFFSET_DDS3 = 3 * phase_offset_step = 0x0083126F
|
|
|
|
-- duration = 10 uS
|
|
-- num_samples = duration / (1/sample_rate)
|
|
-- = 10uS / (1/375MHz)
|
|
-- = 3750
|
|
-- = 0xEA6
|
|
|
|
-- phase_inc_step = (end_phase_inc - start_phase_inc) /num_samples
|
|
-- = (1,156,777,858 - 11,453,246) / 3750
|
|
-- = 305419.8966
|
|
-- = 0x4A90B
|
|
|
|
i_dds_pulse_wrapper_0 : entity work.dds_pulse_wrapper
|
|
generic map (
|
|
DDS_POSITION => 0
|
|
)
|
|
port map (
|
|
s_axi_aclk_in => clk_100,
|
|
s_axi_aresetn_in => clk_100_aresetn(0),
|
|
cmd_idx_in => "000",
|
|
cmd_send_in => cmd_send_0_r(0),
|
|
|
|
mode_in => '0',
|
|
scale_in => x"8000",
|
|
dac_holdoff_in => dac_holdoff_r,
|
|
|
|
reserv1_in => x"00000000",
|
|
dds_phase_inc_dwell_time_in => x"00000000", -- 1MHz to 101 MHz
|
|
dds_phase_inc_step_size_in => x"00000003", --x"00095217", --x"00025485", --x"0000774D", --x"FFFB56F5",-- x"0004A90B",
|
|
idle_samples_in => x"00000000",
|
|
dds_samples_in => x"2CB41780", --x"00000EA6",
|
|
phase_inc_in => x"BBBBBBBC", --x"EEEEEEEF", --x"FC962FCA", --x"44F30782", --x"00AEC33E",
|
|
phase_off_in => x"00000000",
|
|
swap_sf_in => x"00008000",
|
|
|
|
m_axis_aclk_in => clk_375,
|
|
m_axis_aresetn_in => clk_375_aresetn(0),
|
|
m0_axis_tdata_out => m0_dds_intfc_tdata_0,
|
|
m0_axis_tvalid_out => m0_dds_intfc_tvalid_0,
|
|
m0_axis_tready_in => '1',
|
|
|
|
m1_axis_tdata_out => open,
|
|
m1_axis_tvalid_out => open,
|
|
m1_axis_tready_in => '1'
|
|
);
|
|
|
|
i_dds_pulse_wrapper_1 : entity work.dds_pulse_wrapper
|
|
generic map (
|
|
DDS_POSITION => 1
|
|
)
|
|
port map (
|
|
s_axi_aclk_in => clk_100,
|
|
s_axi_aresetn_in => clk_100_aresetn(0),
|
|
cmd_idx_in => "000",
|
|
cmd_send_in => cmd_send_0_r(0),
|
|
|
|
mode_in => '0',
|
|
scale_in => x"8000",
|
|
dac_holdoff_in => dac_holdoff_r,
|
|
|
|
reserv1_in => x"00000000",
|
|
dds_phase_inc_dwell_time_in => x"00000000",
|
|
dds_phase_inc_step_size_in => x"00000003", --x"00095217", --x"00025485", --x"0000774D", --x"FFFB56F5",-- x"0004A90B", --x"00000000", --
|
|
idle_samples_in => x"00000000",
|
|
dds_samples_in => x"2CB41780", --x"00000EA6",
|
|
phase_inc_in => x"BBBBBBBC", --x"EEEEEEEF", --x"FC962FCA", --x"44F30782", --x"00AEC33E",
|
|
phase_off_in => x"00000000",
|
|
swap_sf_in => x"00008000",
|
|
|
|
m_axis_aclk_in => clk_375,
|
|
m_axis_aresetn_in => clk_375_aresetn(0),
|
|
m0_axis_tdata_out => m0_dds_intfc_tdata_1,
|
|
m0_axis_tvalid_out => m0_dds_intfc_tvalid_1,
|
|
m0_axis_tready_in => '1',
|
|
|
|
m1_axis_tdata_out => open,
|
|
m1_axis_tvalid_out => open,
|
|
m1_axis_tready_in => '1'
|
|
);
|
|
|
|
|
|
i_dds_pulse_wrapper_2 : entity work.dds_pulse_wrapper
|
|
generic map (
|
|
DDS_POSITION => 2
|
|
)
|
|
port map (
|
|
s_axi_aclk_in => clk_100,
|
|
s_axi_aresetn_in => clk_100_aresetn(0),
|
|
cmd_idx_in => "000",
|
|
cmd_send_in => cmd_send_0_r(0),
|
|
|
|
mode_in => '0',
|
|
scale_in => x"8000",
|
|
dac_holdoff_in => dac_holdoff_r,
|
|
|
|
reserv1_in => x"00000000",
|
|
dds_phase_inc_dwell_time_in => x"00000000",
|
|
dds_phase_inc_step_size_in => x"00000003", --x"00095217", --x"00025485", --x"0000774D", --x"FFFB56F5",-- x"0004A90B", --x"00000000", --
|
|
idle_samples_in => x"00000000",
|
|
dds_samples_in => x"2CB41780", --x"00000EA6",
|
|
phase_inc_in => x"BBBBBBBC", --x"EEEEEEEF", --x"FC962FCA", --x"44F30782", --x"00AEC33E",
|
|
phase_off_in => x"00000000",
|
|
swap_sf_in => x"00008000",
|
|
|
|
m_axis_aclk_in => clk_375,
|
|
m_axis_aresetn_in => clk_375_aresetn(0),
|
|
m0_axis_tdata_out => m0_dds_intfc_tdata_2,
|
|
m0_axis_tvalid_out => m0_dds_intfc_tvalid_2,
|
|
m0_axis_tready_in => '1',
|
|
|
|
m1_axis_tdata_out => open,
|
|
m1_axis_tvalid_out => open,
|
|
m1_axis_tready_in => '1'
|
|
);
|
|
|
|
|
|
i_dds_pulse_wrapper_3 : entity work.dds_pulse_wrapper
|
|
generic map (
|
|
DDS_POSITION => 3
|
|
)
|
|
port map (
|
|
s_axi_aclk_in => clk_100,
|
|
s_axi_aresetn_in => clk_100_aresetn(0),
|
|
cmd_idx_in => "000",
|
|
cmd_send_in => cmd_send_0_r(0),
|
|
|
|
mode_in => '0',
|
|
scale_in => x"8000",
|
|
dac_holdoff_in => dac_holdoff_r,
|
|
|
|
reserv1_in => x"00000000",
|
|
dds_phase_inc_dwell_time_in => x"00000000",
|
|
dds_phase_inc_step_size_in => x"00000003", --x"00095217", --x"00025485", --x"0000774D", --x"FFFB56F5",-- x"0004A90B", --x"00000000", --
|
|
idle_samples_in => x"00000000",
|
|
dds_samples_in => x"2CB41780", --x"00000EA6",
|
|
phase_inc_in => x"BBBBBBBC", --x"EEEEEEEF", --x"FC962FCA", --x"44F30782", --x"00AEC33E",
|
|
phase_off_in => x"00000000",
|
|
swap_sf_in => x"00008000",
|
|
|
|
m_axis_aclk_in => clk_375,
|
|
m_axis_aresetn_in => clk_375_aresetn(0),
|
|
m0_axis_tdata_out => m0_dds_intfc_tdata_3,
|
|
m0_axis_tvalid_out => m0_dds_intfc_tvalid_3,
|
|
m0_axis_tready_in => '1',
|
|
|
|
m1_axis_tdata_out => open,
|
|
m1_axis_tvalid_out => open,
|
|
m1_axis_tready_in => '1'
|
|
);
|
|
|
|
chan0_i <= m0_dds_intfc_tdata_0(15 downto 0);
|
|
chan0_q <= m0_dds_intfc_tdata_0(31 downto 16);
|
|
chan1_i <= m0_dds_intfc_tdata_1(15 downto 0);
|
|
chan1_q <= m0_dds_intfc_tdata_1(31 downto 16);
|
|
chan2_i <= m0_dds_intfc_tdata_2(15 downto 0);
|
|
chan2_q <= m0_dds_intfc_tdata_2(31 downto 16);
|
|
chan3_i <= m0_dds_intfc_tdata_3(15 downto 0);
|
|
chan3_q <= m0_dds_intfc_tdata_3(31 downto 16);
|
|
|
|
|
|
-- display data at 1.5 GSPS
|
|
process(clk_375)
|
|
begin
|
|
if (rising_edge(clk_375)) then
|
|
dac_r <= transport chan0_i after 0 ns;
|
|
dac_r <= transport chan1_i after 0.6667 ns;
|
|
dac_r <= transport chan2_i after 1.3334 ns;
|
|
dac_r <= transport chan3_i after 2.0001 ns;
|
|
|
|
dac_idx_r <= transport "00" after 0 ns;
|
|
dac_idx_r <= transport "01" after 0.6667 ns;
|
|
dac_idx_r <= transport "10" after 1.3334 ns;
|
|
dac_idx_r <= transport "11" after 2.0001 ns;
|
|
|
|
end if;
|
|
end process;
|
|
|
|
dac_i <= dac_r;
|
|
|
|
|
|
|
|
|
|
|
|
-- Stimulus process
|
|
stim_proc: process
|
|
begin
|
|
|
|
wait until clk_100_aresetn(0) = '1';
|
|
|
|
-- wait for 24 us;
|
|
|
|
wait until rising_edge(clk_375);
|
|
-- m_axis_tready_r <= '1';
|
|
wait for 1 us;
|
|
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(0) <= '1';
|
|
wait for 200 ns;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(0) <= '0';
|
|
wait for 1 us;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(1) <= '1';
|
|
wait for 200 ns;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(1) <= '0';
|
|
|
|
wait for 1 us;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(2) <= '1';
|
|
wait for 200 ns;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(2) <= '0';
|
|
|
|
wait for 1 us;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(3) <= '1';
|
|
wait for 200 ns;
|
|
wait until rising_edge(clk_100);
|
|
cmd_send_i(3) <= '0';
|
|
|
|
wait for 1 us;
|
|
wait until rising_edge(clk_100);
|
|
dac_holdoff_r <= '0';
|
|
|
|
|
|
wait for 8 us;
|
|
cnt_reset <= '1';
|
|
wait until rising_edge(clk_100);
|
|
cnt_reset <= '0';
|
|
|
|
-- m_axis_tready_r <= '0';
|
|
-- wait until rising_edge(clk_375);
|
|
|
|
|
|
-- m_axis_tready_r <= '1';
|
|
-- wait until rising_edge(clk_375);
|
|
|
|
|
|
-- m_axis_tready_r <= '0';
|
|
-- wait until rising_edge(clk_375);
|
|
|
|
|
|
-- m_axis_tready_r <= '1';
|
|
|
|
wait until rising_edge(clk_100);
|
|
|
|
wait; -- wait here forever
|
|
end process;
|
|
|
|
|
|
|
|
end;
|