-------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 17:16:42 13.05.2007 -- Design Name: tb_nco -- Module Name: tb_nco.vhd -- Project Name: nco -- Target Device: -- Tool versions: -- Description: -- -------------------------------------------------------------------------------- LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; use IEEE.MATH_REAL.ALL; USE ieee.numeric_std.ALL; library ieee_proposed; use ieee_proposed.fixed_float_types.all; use ieee_proposed.fixed_pkg.all; --library altera; --use altera.altera_syn_attributes.all; library work; use work.fixed_util_pkg.all; ENTITY syn_ddc IS Generic ( nbits_in : integer := 16; nbits_in_frac : integer := 14; nbits_out : integer := 32; nbits_out_frac : integer := 30; lo_nbits_phase : integer := 24; lo_nbits_freq : integer := 24; cic_nstages : integer := 5; cic_ratio : integer := 25; cic_scale_nbits : integer := 22 ); PORT ( rst : in std_logic; adc_clk : in std_logic; adc_da : in signed(15 downto 0); adc_ofa : in std_logic; adc_rand : out std_logic; adc_pga : out std_logic; adc_dith : out std_logic; adc_shdn : out std_logic; usb_usbclk : in std_logic; usb_ifclk : in std_logic; usb_fd : out signed(15 downto 0); usb_pktend : out std_logic; usb_fifoadr : out unsigned(1 downto 0); usb_slcs_n : out std_logic; usb_slwr_n : out std_logic; usb_slrd_n : out std_logic; usb_sloe : out std_logic; usb_flaga : in std_logic; usb_flagb : in std_logic; usb_flagc : in std_logic; cl_clk_out : out std_logic; cl_dout : out unsigned(20 downto 0); cl_pd_n : out std_logic; reg_aen : in std_logic; reg_dio : inout unsigned(7 downto 0); reg_oe : in std_logic; reg_we : in std_logic ); END syn_ddc; ARCHITECTURE behavior OF syn_ddc IS -- Component Declaration for the Unit Under Test (UUT) COMPONENT ddc GENERIC ( nbits_in : integer; nbits_in_frac : integer; nbits_out : integer; nbits_out_frac : integer; lo_nbits_phase : integer; lo_nbits_freq : integer; cic_nstages : integer; cic_ratio : integer; cic_scale_nbits : integer ); PORT ( rst : in std_logic; clk : in std_logic; lo_nco_rst : in std_logic; lo_nco_en : in std_logic; lo_freq_in : in unsigned(lo_nbits_freq-1 downto 0); lo_phase_in : in unsigned(lo_nbits_phase-1 downto 0); din_vld : in std_logic; din_i : in sfixed; din_q : in sfixed; dec_vld : out std_logic; dec_i : out sfixed; dec_q : out sfixed; dout_vld : out std_logic; dout_i : out sfixed; dout_q : out sfixed ); END COMPONENT; --Outputs SIGNAL ddc_din_i : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); SIGNAL ddc_din_q : sfixed(shi(nbits_in, nbits_in_frac) downto slo(nbits_in, nbits_in_frac)); SIGNAL ddc_dout_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL ddc_dout_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL dec_vld : std_logic; SIGNAL ddc_dec_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL ddc_dec_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL reg_lo_nco_rst : std_logic; SIGNAL reg_lo_nco_en : std_logic; SIGNAL reg_lo_freq_in : unsigned(31 downto 0); SIGNAL reg_lo_phase_in : unsigned(31 downto 0); SIGNAL reg_en_addr : std_logic; SIGNAL reg_en_data : std_logic; SIGNAL reg_addr_last : std_logic; SIGNAL reg_data_last : std_logic; SIGNAL reg_addr_async : unsigned (7 downto 0); SIGNAL reg_data_async : unsigned (7 downto 0); SIGNAL reg_addr : unsigned (7 downto 0); SIGNAL reg_data : unsigned (7 downto 0); SIGNAL fifo_usb_we : std_logic; SIGNAL fifo_usb_re : std_logic; SIGNAL fifo_usb_ff : std_logic; SIGNAL fifo_usb_ef : std_logic; SIGNAL fifo_usb_aff : std_logic; SIGNAL fifo_usb_aef : std_logic; type fifo_usb_array_t is array (0 to 3) of unsigned (15 downto 0); SIGNAL fifo_usb_in : fifo_usb_array_t; SIGNAL fifo_usb_out : unsigned (15 downto 0); SIGNAL cl_clk : std_logic; SIGNAL fifo_cl_we : std_logic; SIGNAL fifo_cl_re : std_logic; SIGNAL fifo_cl_ff : std_logic; SIGNAL fifo_cl_ef : std_logic; SIGNAL fifo_cl_aff : std_logic; SIGNAL fifo_cl_aef : std_logic; SIGNAL fifo_cl_in : unsigned (63 downto 0); SIGNAL fifo_cl_out : unsigned (63 downto 0); SIGNAL fifo_usb_we_pipe : unsigned(3 downto 0); SIGNAL enable : std_logic; SIGNAL ddc_din_vld : std_logic; SIGNAL ddc_dout_vld : std_logic; SIGNAL cl_rst_pipe : unsigned (63 downto 0); SIGNAL cl_rst : std_logic; SIGNAL cl_phase : unsigned(1 downto 0); SIGNAL cl_data : unsigned(20 downto 0); subtype cl_clkgen_cnt_t is natural range 0 to (2*cic_ratio/2/5)-1; SIGNAL cl_clkgen_cnt : cl_clkgen_cnt_t; BEGIN -- Instantiate the Unit Under Test (UUT) inst_ddc : ddc GENERIC MAP ( nbits_in => nbits_in, nbits_in_frac => nbits_in_frac, nbits_out => nbits_out, nbits_out_frac => nbits_out_frac, lo_nbits_phase => lo_nbits_phase, lo_nbits_freq => lo_nbits_freq, cic_nstages => cic_nstages, cic_ratio => cic_ratio, cic_scale_nbits => cic_scale_nbits ) PORT MAP ( rst => rst, clk => adc_clk, lo_nco_rst => reg_lo_nco_rst, lo_nco_en => reg_lo_nco_en, lo_freq_in => reg_lo_freq_in(lo_nbits_freq-1 downto 0), lo_phase_in => reg_lo_phase_in(lo_nbits_phase-1 downto 0), din_vld => ddc_din_vld, din_i => ddc_din_i, din_q => ddc_din_q, dec_vld => dec_vld, dec_i => ddc_dec_i, dec_q => ddc_dec_q, dout_vld => ddc_dout_vld, dout_i => ddc_dout_i, dout_q => ddc_dout_q ); reg_dio <= reg_addr when reg_oe = '1' else (others => 'Z'); ---------------------------------------------------------- -- Register control ---------------------------------------------------------- proc_reg_da_async: process(reg_we) begin if rising_edge(reg_we) then if reg_aen = '1' then reg_addr_async <= reg_dio; else reg_data_async <= reg_dio; end if; end if; end process; proc_reg_da_sync: process(adc_clk) -- process(usb_usbclk) begin if rising_edge(adc_clk) then -- if rising_edge(usb_usbclk) then if rst = '1' then reg_en_addr <= '0'; reg_en_data <= '0'; reg_addr_last <= '0'; reg_data_last <= '0'; elsif reg_we = '1' then reg_en_addr <= reg_aen and not reg_addr_last; reg_en_data <= not (reg_aen or reg_data_last); reg_addr_last <= reg_aen; reg_data_last <= not reg_aen; else reg_addr_last <= '0'; reg_data_last <= '0'; end if; reg_data <= reg_data_async; reg_addr <= reg_addr_async; end if; end process; -- Registers proc_register_write: process(adc_clk) -- process(usb_usbclk) begin if rising_edge(adc_clk) then -- if rising_edge(usb_usbclk) then if rst = '1' then reg_lo_nco_rst <= '1'; reg_lo_nco_en <= '0'; elsif reg_en_data = '1' then case reg_addr is when X"00" => -- Control reg_lo_nco_rst <= reg_data(0); reg_lo_nco_en <= reg_data(1); when X"10" => -- freqency reg_lo_freq_in(7 downto 0) <= reg_data; when X"11" => -- freqency reg_lo_freq_in(15 downto 8) <= reg_data; when X"12" => -- freqency reg_lo_freq_in(23 downto 16) <= reg_data; when X"13" => -- freqency reg_lo_freq_in(31 downto 24) <= reg_data; when X"20" => -- phase reg_lo_phase_in(7 downto 0) <= reg_data; when X"21" => -- phase reg_lo_phase_in(15 downto 8) <= reg_data; when X"22" => -- phase reg_lo_phase_in(23 downto 16) <= reg_data; when X"23" => -- phase reg_lo_phase_in(31 downto 24) <= reg_data; when others => null; end case; end if; end if; end process; ---------------------------------------------------------- -- DDC input ---------------------------------------------------------- proc_adc_input_register: process(adc_clk) begin if rising_edge(adc_clk) then ddc_din_i <= sfixed(resize(adc_da, nbits_in)); ddc_din_vld <= reg_lo_nco_en; end if; end process; ddc_din_q <= to_sfixed(0.0, shi(nbits_in, nbits_in_frac), slo(nbits_in, nbits_in_frac)); adc_rand <= '0'; adc_pga <= '0'; adc_dith <= '0'; adc_shdn <= not reg_lo_nco_en; ---------------------------------------------------------- -- USB FIFO output ---------------------------------------------------------- proc_usb_interleave_iq: process(adc_clk) variable i, q : unsigned(31 downto 0); begin if rising_edge(adc_clk) then if rst = '1' then fifo_usb_we_pipe <= (others => '0'); elsif ddc_dout_vld = '1' then fifo_usb_we_pipe <= (others => '1'); i := to_unsigned(ufixed(ddc_dout_i)); q := to_unsigned(ufixed(ddc_dout_q)); fifo_usb_in(0) <= i(15 downto 0); fifo_usb_in(1) <= i(31 downto 16); fifo_usb_in(2) <= q(15 downto 0); fifo_usb_in(3) <= q(31 downto 16); elsif fifo_usb_ff = '0' then fifo_usb_we_pipe <= fifo_usb_we_pipe(fifo_usb_we_pipe'left-1 downto 0) & '0'; fifo_usb_in(0) <= fifo_usb_in(1); fifo_usb_in(1) <= fifo_usb_in(2); fifo_usb_in(2) <= fifo_usb_in(3); end if; end if; end process; inst_usbfifo: entity work.fifo_async GENERIC MAP ( addr_width => 7, data_width => 16, almost_full_thresh => 96, almost_empty_thresh => 32 ) PORT MAP ( rst => rst, clk_w => adc_clk, clk_r => usb_ifclk, we => fifo_usb_we, re => fifo_usb_re, data_w => fifo_usb_in(0), data_r => fifo_usb_out, fifo_full => fifo_usb_ff, fifo_empty => fifo_usb_ef, fifo_afull => fifo_usb_aff, fifo_aempty => fifo_usb_aef ); fifo_usb_we <= fifo_usb_we_pipe(fifo_usb_we_pipe'left); usb_fd <= signed(fifo_usb_out); fifo_usb_re <= usb_flaga; usb_slcs_n <= '0'; usb_slwr_n <= not usb_flaga; usb_slrd_n <= '1'; usb_sloe <= '0'; ---------------------------------------------------------- -- Channel-Link output ---------------------------------------------------------- inst_cl_fifo: entity work.fifo_async GENERIC MAP ( addr_width => 4, data_width => 64, almost_full_thresh => 96, almost_empty_thresh => 32 ) PORT MAP ( rst => rst, clk_w => adc_clk, clk_r => cl_clk, we => fifo_cl_we, re => fifo_cl_re, data_w => fifo_cl_in, data_r => fifo_cl_out, fifo_full => fifo_cl_ff, fifo_empty => fifo_cl_ef, fifo_afull => fifo_cl_aff, fifo_aempty => fifo_cl_aef ); fifo_cl_in <= to_unsigned(ufixed(ddc_dout_i)) & to_unsigned(ufixed(ddc_dout_i)); fifo_cl_we <= ddc_dout_vld; fifo_cl_re <= '1'; proc_cl_clkgen: process(adc_clk) begin if rising_edge(adc_clk) then if rst = '1' then cl_rst_pipe <= (others => '1'); cl_clkgen_cnt <= cl_clkgen_cnt_t'high; cl_clk <= '0'; else if cl_clkgen_cnt = 0 then cl_clkgen_cnt <= cl_clkgen_cnt_t'high; cl_clk <= not cl_clk; cl_rst_pipe <= cl_rst_pipe(cl_rst_pipe'left-1 downto 0) & '0'; else cl_clkgen_cnt <= cl_clkgen_cnt - 1; end if; end if; end if; end process; cl_rst <= cl_rst_pipe(cl_rst_pipe'left); proc_cl_interleave_iq: process(cl_clk) variable i, q : unsigned(31 downto 0); begin if rising_edge(cl_clk) then if cl_rst = '1' then cl_phase <= (others => '0'); else i := fifo_cl_out(31 downto 0); q := fifo_cl_out(63 downto 32); if cl_phase(1) = '0' then if cl_phase(0) = '0' then cl_data <= not fifo_cl_ef & cl_phase & "00" & i(15 downto 0); else cl_data <= not fifo_cl_ef & cl_phase & "00" & i(31 downto 16); end if; else if cl_phase(0) = '0' then cl_data <= not fifo_cl_ef & cl_phase & "00" & q(15 downto 0); else cl_data <= not fifo_cl_ef & cl_phase & "00" & q(31 downto 16); end if; end if; cl_phase <= cl_phase + 1; end if; end if; end process; cl_dout <= cl_data; cl_clk_out <= cl_clk; cl_pd_n <= not cl_rst; ---------------------------------------------------------- END;