------------------------------------------------------------------------------- -- Company: -- Engineer: Jason M. Blevins -- -- Create Date: 19:38:12 11/10/2016 -- Design Name: -- Module Name: dds_pulse_2x_top - behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- * All information is proprietary/confidential * -- -- Supports single channel mode or dual channel (summed) mode. -- When using dual channel mode, the module hangs after the shortest of the -- two pulse streams completes. Ideally, both streams will be equal length. -- -- For each channel: -- A 256-bit control word (32x8 right shifted in) is read from an external FIFO. -- The control word contains all information needed to create a pulse -- -- RESERVED = fifo_data_r(255 downto 241) -- 15-bits -- SWAP IQ CHANELS = fifo_data_r(240) -- 1-bit set to '1' for negative frequencies -- SCALE FACTOR TO SCALE OUTPUT AMPLITUDE = fifo_data_r(239 downto 224) -- 16-bits, (0,1], full-scale = 1.000000000000000 -- DDS PHASE OFFSET = fifo_data_r(223 downto 192) -- 32-bits, reserved, set to 0x0000_0000 -- DDS PHASE INCREMENT = fifo_data_r(191 downto 160) -- 32-bits -- # DDS SAMPLES = fifo_data_r(159 downto 128) -- 32-bits -- # MIDPOINT SAMPLES PRIOR TO PULSE = fifo_data_r(127 downto 96) -- 32-bits -- RESERVED = fifo_data_r(95 downto 88) -- 8-bit -- DDS PHASE INCREMENT STEP = fifo_data_r(87 downto 64) -- 24-bits (2's complement SIGNED !!) -- RESERVED = fifo_data_r(63 downto 48) -- 16-bits -- DDS PHASE INCREMENT DWELL = fifo_data_r(47 downto 32) -- 16-bits -- ------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; --Library UNIMACRO; --use UNIMACRO.vcomponents.all; USE IEEE.NUMERIC_STD.ALL; entity dds_pulse_2x_top is port( clk_in : in std_logic; rst_in : in std_logic; mode_in : in std_logic; -- 0=single, 1=dual scale_in : in std_logic_vector(15 downto 0); fifo1_data_in : in std_logic_vector(31 downto 0); fifo1_dval_in : in std_logic; fifo1_empty_in : in std_logic; fifo1_rden_out : out std_logic; fifo2_data_in : in std_logic_vector(31 downto 0); fifo2_dval_in : in std_logic; fifo2_empty_in : in std_logic; fifo2_rden_out : out std_logic; holdoff_in : in std_logic; overflow_out : out std_logic_vector(1 downto 0); underflow_out : out std_logic_vector(1 downto 0); i_max_abs_out : out std_logic_vector(15 downto 0); q_max_abs_out : out std_logic_vector(15 downto 0); data_out : out std_logic_vector(31 downto 0); dval_out : out std_logic ); end entity; architecture mixed of dds_pulse_2x_top is component mult_16signed_x_16unsigned_latency3 port( clk : in std_logic; a : in std_logic_vector(15 downto 0); b : in std_logic_vector(15 downto 0); ce : in std_logic; sclr : in std_logic; p : out std_logic_vector(15 downto 0) ); end component; component dds_pulse_gen is port( clk_in : in std_logic; rst_in : in std_logic; fifo_data_in : in std_logic_vector(31 downto 0); fifo_dval_in : in std_logic; fifo_empty_in : in std_logic; fifo_rden_out : out std_logic; holdoff_in : in std_logic; data_out : out std_logic_vector(31 downto 0); dval_out : out std_logic ); end component; component sfifo_32b_1024_pf992_latency1 port( clk : in std_logic; srst : in std_logic; din : in std_logic_vector(31 downto 0); wr_en : in std_logic; rd_en : in std_logic; dout : out std_logic_vector(31 downto 0); full : out std_logic; overflow : out std_logic; empty : out std_logic; underflow : out std_logic; prog_full : out std_logic ); end component; component adder_16signed_16signed_latency2 port( a : in std_logic_vector(15 downto 0); b : in std_logic_vector(15 downto 0); clk : in std_logic; ce : in std_logic; bypass : in std_logic; s : out std_logic_vector(16 downto 0) ); end component; signal rst_r : std_logic := '1'; signal mode_n_r : std_logic := '1'; -- 1=single, 0=dual signal scale_r : std_logic_vector(15 downto 0) := x"8000"; signal pulse_fifo_dval_r : std_logic_vector(1 downto 0) := "00"; signal pulse_adder_dval_r : std_logic := '0'; signal pulse_adder_ce : std_logic; signal pulse_data_r : std_logic_vector(31 downto 0) := (others => '0'); signal pulse_dval_r : std_logic := '0'; signal adder_dval_r : std_logic := '0'; signal holdoff_r : std_logic; signal pulse1_mult_dval_r : std_logic := '0'; signal pulse1_mult_ce_pipe_r : std_logic_vector(1 downto 0) := "00"; signal pulse1_mult_ce : std_logic; signal pulse1_data : std_logic_vector(31 downto 0); signal pulse1_dval : std_logic; signal pulse1_data_scaled : std_logic_vector(31 downto 0); signal pulse1_fifo_overflow : std_logic; signal pulse1_fifo_empty : std_logic; signal pulse1_fifo_underflow : std_logic; signal pulse1_fifo_progfull : std_logic; signal pulse1_fifo_rden : std_logic; signal pulse1_fifo_rden_r : std_logic := '0'; signal pulse1_fifo_dout : std_logic_vector(31 downto 0); signal pulse1_fifo_dout_r : std_logic_vector(31 downto 0) := (others => '0'); signal adder1_s : std_logic_vector(16 downto 0); signal adder1_s_r : std_logic_vector(16 downto 0); signal adder1_s_r1 : std_logic_vector(15 downto 0); signal i_abs_max_r : unsigned(15 downto 0); signal fifo1_underflow_r : std_logic := '0'; signal fifo1_overflow_r : std_logic := '0'; signal pulse2_mult_dval_r : std_logic := '0'; signal pulse2_mult_ce_pipe_r : std_logic_vector(1 downto 0) := "00"; signal pulse2_mult_ce : std_logic; signal pulse2_data : std_logic_vector(31 downto 0); signal pulse2_dval : std_logic; signal pulse2_data_scaled : std_logic_vector(31 downto 0); signal pulse2_fifo_overflow : std_logic; signal pulse2_fifo_empty : std_logic; signal pulse2_fifo_underflow : std_logic; signal pulse2_fifo_progfull : std_logic; signal pulse2_fifo_rden : std_logic; signal pulse2_fifo_dout : std_logic_vector(31 downto 0); signal pulse2_fifo_dout_r : std_logic_vector(31 downto 0); signal adder2_s : std_logic_vector(16 downto 0); signal adder2_s_r : std_logic_vector(16 downto 0); signal adder2_s_r1 : std_logic_vector(15 downto 0); signal q_abs_max_r : unsigned(15 downto 0); signal fifo2_underflow_r : std_logic := '0'; signal fifo2_overflow_r : std_logic := '0'; begin data_out <= pulse_data_r; dval_out <= pulse_dval_r; i_max_abs_out <= std_logic_vector(i_abs_max_r); q_max_abs_out <= std_logic_vector(q_abs_max_r); overflow_out <= fifo2_overflow_r & fifo1_overflow_r; underflow_out <= fifo2_underflow_r & fifo1_underflow_r; process(clk_in) begin if(rising_edge(clk_in))then rst_r <= rst_in; scale_r <= scale_in; mode_n_r <= not(mode_in); holdoff_r <= holdoff_in; end if; end process; process(clk_in) begin if(rising_edge(clk_in))then pulse1_mult_dval_r <= pulse1_mult_ce_pipe_r(1); pulse1_mult_ce_pipe_r(1 downto 0) <= pulse1_mult_ce_pipe_r(0) & pulse1_dval; pulse2_mult_dval_r <= pulse2_mult_ce_pipe_r(1); pulse2_mult_ce_pipe_r(1 downto 0) <= pulse2_mult_ce_pipe_r(0) & pulse2_dval; pulse_fifo_dval_r(1 downto 0) <= pulse_fifo_dval_r(0) & pulse1_fifo_rden_r; pulse_adder_dval_r <= pulse_fifo_dval_r(1); pulse1_fifo_rden_r <= pulse1_fifo_rden; pulse1_fifo_dout_r <= pulse1_fifo_dout; pulse2_fifo_dout_r <= pulse2_fifo_dout; end if; end process; pulse1_mult_ce <= pulse1_mult_ce_pipe_r(1) or pulse1_mult_ce_pipe_r(0) or pulse1_dval; pulse2_mult_ce <= pulse2_mult_ce_pipe_r(1) or pulse2_mult_ce_pipe_r(0) or pulse2_dval; pulse1_fifo_rden <= not(pulse1_fifo_empty) and not(pulse2_fifo_empty) and not(holdoff_r) when mode_n_r = '0' else not(pulse1_fifo_empty) and not(holdoff_r); pulse2_fifo_rden <= not(pulse1_fifo_empty) and not(pulse2_fifo_empty) and not(holdoff_r) when mode_n_r = '0' else '0'; pulse_adder_ce <= pulse_fifo_dval_r(1) or pulse_fifo_dval_r(0); i_dds_pulse1_gen : dds_pulse_gen port map( clk_in => clk_in, rst_in => rst_r, fifo_data_in => fifo1_data_in, fifo_dval_in => fifo1_dval_in, fifo_empty_in => fifo1_empty_in, fifo_rden_out => fifo1_rden_out, holdoff_in => pulse1_fifo_progfull, data_out => pulse1_data, dval_out => pulse1_dval ); i_pulse1_mult1 : mult_16signed_x_16unsigned_latency3 port map( clk => clk_in, a => pulse1_data(15 downto 0), b => scale_r, ce => pulse1_mult_ce, sclr => '0', p => pulse1_data_scaled(15 downto 0) ); i_pulse1_mult2 : mult_16signed_x_16unsigned_latency3 port map( clk => clk_in, a => pulse1_data(31 downto 16), b => scale_r, ce => pulse1_mult_ce, sclr => '0', p => pulse1_data_scaled(31 downto 16) ); i_pulse1_fifo : sfifo_32b_1024_pf992_latency1 port map( clk => clk_in, srst => rst_r, din => pulse1_data_scaled, wr_en => pulse1_mult_dval_r, rd_en => pulse1_fifo_rden, dout => pulse1_fifo_dout, full => open, overflow => pulse1_fifo_overflow, empty => pulse1_fifo_empty, underflow => pulse1_fifo_underflow, prog_full => pulse1_fifo_progfull ); i_dds_pulse2_gen : dds_pulse_gen port map( clk_in => clk_in, rst_in => rst_r, fifo_data_in => fifo2_data_in, fifo_dval_in => fifo2_dval_in, fifo_empty_in => fifo2_empty_in, fifo_rden_out => fifo2_rden_out, holdoff_in => pulse2_fifo_progfull, data_out => pulse2_data, dval_out => pulse2_dval ); i_pulse2_mult1 : mult_16signed_x_16unsigned_latency3 port map( clk => clk_in, a => pulse2_data(15 downto 0), b => scale_r, ce => pulse2_mult_ce, sclr => '0', p => pulse2_data_scaled(15 downto 0) ); i_pulse2_mult2 : mult_16signed_x_16unsigned_latency3 port map( clk => clk_in, a => pulse2_data(31 downto 16), b => scale_r, ce => pulse2_mult_ce, sclr => '0', p => pulse2_data_scaled(31 downto 16) ); i_pulse2_fifo : sfifo_32b_1024_pf992_latency1 port map( clk => clk_in, srst => rst_r, din => pulse2_data_scaled, wr_en => pulse2_mult_dval_r, rd_en => pulse2_fifo_rden, dout => pulse2_fifo_dout, full => open, overflow => pulse2_fifo_overflow, empty => pulse2_fifo_empty, underflow => pulse2_fifo_underflow, prog_full => pulse2_fifo_progfull ); i_pulse_adder1 : adder_16signed_16signed_latency2 port map( a => pulse2_fifo_dout_r(15 downto 0), b => pulse1_fifo_dout_r(15 downto 0), clk => clk_in, ce => pulse_adder_ce, bypass => mode_n_r, -- when set to '1', b input proceeds to s output s => adder1_s ); i_pulse_adder2 : adder_16signed_16signed_latency2 port map( a => pulse2_fifo_dout_r(31 downto 16), b => pulse1_fifo_dout_r(31 downto 16), clk => clk_in, ce => pulse_adder_ce, bypass => mode_n_r, -- when set to '1', b input proceeds to s output s => adder2_s ); process(clk_in) begin if(rising_edge(clk_in))then adder1_s_r <= adder1_s; adder2_s_r <= adder2_s; adder_dval_r <= pulse_adder_dval_r; pulse_dval_r <= adder_dval_r; if(adder_dval_r = '1')then case adder1_s_r(16 downto 15) is when "01" => --positive overflow pulse_data_r(15 downto 0) <= x"7FFF"; when "10" => --negative overflow pulse_data_r(15 downto 0) <= x"8000"; when others => pulse_data_r(15 downto 0) <= adder1_s_r(16) & adder1_s_r(14 downto 0); end case; case adder2_s_r(16 downto 15) is when "01" => --positive overflow pulse_data_r(31 downto 16) <= x"7FFF"; when "10" => --negative overflow pulse_data_r(31 downto 16) <= x"8000"; when others => pulse_data_r(31 downto 16) <= adder2_s_r(16) & adder2_s_r(14 downto 0); end case; end if; if(rst_r = '1')then --adder_dval_r <= '0'; --pulse_dval_r <= '0'; i_abs_max_r <= (others => '0'); q_abs_max_r <= (others => '0'); fifo1_overflow_r <= '0'; fifo1_underflow_r <= '0'; fifo2_overflow_r <= '0'; fifo2_underflow_r <= '0'; else --adder_dval_r <= pulse_adder_dval_r; --pulse_dval_r <= adder_dval_r; if(pulse1_fifo_overflow = '1')then fifo1_overflow_r <= '1'; end if; if(pulse1_fifo_underflow = '1')then fifo1_underflow_r <= '1'; end if; if(pulse2_fifo_overflow = '1')then fifo2_overflow_r <= '1'; end if; if(pulse2_fifo_underflow = '1')then fifo2_underflow_r <= '1'; end if; if(adder_dval_r = '1')then -- if(abs(signed(adder1_s_r)) > i_abs_max_r)then -- i_abs_max_r <= abs(signed(adder1_s_r)); -- end if; if(adder1_s_r(16) = '0')then adder1_s_r1 <= adder1_s_r(15 downto 0); else adder1_s_r1 <= not(adder1_s_r(15 downto 0)); end if; -- if(abs(signed(adder2_s_r)) > q_abs_max_r)then -- q_abs_max_r <= abs(signed(adder2_s_r)); -- end if; if(adder2_s_r(16) = '0')then adder2_s_r1 <= adder2_s_r(15 downto 0); else adder2_s_r1 <= not(adder2_s_r(15 downto 0)); end if; end if; if(pulse_dval_r = '1')then if(unsigned(adder1_s_r1) > i_abs_max_r)then i_abs_max_r <= unsigned(adder1_s_r1); end if; if(unsigned(adder2_s_r1) > q_abs_max_r)then q_abs_max_r <= unsigned(adder2_s_r1); end if; end if; end if; end if; end process; end mixed;