-------------------------------------------------------------------------------- -- 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 work; use work.utils_pkg.all; use work.fixed_util_pkg.all; use work.filter_pkg.all; use work.fir_pkg.all; ENTITY ddc IS Generic ( nbits_in : integer := 18; nbits_in_frac : integer := 16; nbits_out : integer := 18; nbits_out_frac : integer := 16; lo_nbits_phase : integer := 20; lo_nbits_freq : integer := 20; cic_nstages : integer := 3; cic_ratio : integer := 64; cic_scale_nbits : integer := 18 ); 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_i : in sfixed; din_q : in sfixed; din_vld : in std_logic; dec_i : out sfixed; dec_q : out sfixed; dec_vld : out std_logic; dout_i : out sfixed; dout_q : out sfixed; dout_vld : out std_logic ); END ddc; ARCHITECTURE behavior OF ddc IS -- Component Declaration for the Unit Under Test (UUT) COMPONENT mix GENERIC ( nbits_din : integer; nbits_din_frac : integer; nbits_dout : integer; nbits_dout_frac : integer; nbits_phase : integer; nbits_freq : integer ); PORT ( rst : in std_logic; clk : in std_logic; nco_rst : in std_logic; nco_en : in std_logic; freq_in : in unsigned(nbits_freq-1 downto 0); phase_in : in unsigned(nbits_phase-1 downto 0); din_i : in sfixed; din_q : in sfixed; dout_i : out sfixed; dout_q : out sfixed; din_vld : in std_logic; dout_vld : out std_logic ); END COMPONENT; COMPONENT cic_decim_pipe GENERIC ( nstages : integer; ratio : integer; scale_nbits : integer; in_width : integer; in_width_frac : integer; out_width : integer; out_width_frac : integer ); PORT ( clk : in std_logic; rst : in std_logic; vld_in : in std_logic; din : in sfixed; dout : out sfixed; vld_out : out std_logic ); END COMPONENT; COMPONENT fifo_sync GENERIC ( addr_width : natural; data_width : natural; almost_full_thresh : integer; almost_empty_thresh : integer ); PORT ( rst : in STD_LOGIC; clk : in STD_LOGIC; we : in STD_LOGIC; re : in STD_LOGIC; fifo_full : out STD_LOGIC; fifo_empty : out STD_LOGIC; fifo_afull : out STD_LOGIC; fifo_aempty : out STD_LOGIC; data_w : in unsigned (data_width-1 downto 0); data_r : out unsigned (data_width-1 downto 0) ); END COMPONENT; COMPONENT fir_semi_parallel GENERIC ( ntaps_per_stage : integer; nstages : integer; pipe_latency : integer; nbits_in : integer; nbits_in_frac : integer; nbits_stages : integer; nbits_stages_frac : integer; nbits_out : integer; nbits_out_frac : integer ); PORT ( rst : in std_logic; clk : in std_logic; h_addr : in natural range 0 to nstages*ntaps_per_stage-1; h_we : in std_logic; h_in : in sfixed; din_vld : in std_logic; din : in sfixed; dout_vld : out std_logic; rdy : out std_logic; dout : out sfixed ); END COMPONENT; constant lo_nbits_in : integer := nbits_in; constant lo_nbits_in_frac : integer := nbits_in_frac; constant lo_nbits_out : integer := nbits_in; constant lo_nbits_out_frac : integer := nbits_in_frac; constant cic_nbits_in : integer := lo_nbits_out; constant cic_nbits_in_frac : integer := lo_nbits_out_frac; constant cic_nbits_out : integer := nbits_out; constant cic_nbits_out_frac : integer := nbits_out_frac; constant cfir_pipe_latency : integer := 5; constant cfir_ntaps : integer := 63; constant cfir_nstages : integer := 2; constant cfir_nbits_in : integer := cic_nbits_out; constant cfir_nbits_in_frac : integer := cic_nbits_out_frac; constant cfir_nbits_out : integer := nbits_out; constant cfir_nbits_out_frac : integer := nbits_out_frac; constant cfir_nbits_stages : integer := cfir_nbits_in; constant cfir_nbits_stages_frac : integer := cfir_nbits_in_frac; constant cfir_ntaps_per_stage : integer := NextPowerOfTwo(cfir_ntaps)/cfir_nstages; SIGNAL mix_dout_i : sfixed(shi(lo_nbits_out, lo_nbits_out_frac) downto slo(lo_nbits_out, lo_nbits_out_frac)); SIGNAL mix_dout_q : sfixed(shi(lo_nbits_out, lo_nbits_out_frac) downto slo(lo_nbits_out, lo_nbits_out_frac)); SIGNAL mix_dout_vld : std_logic; SIGNAL dec_dout_i : sfixed(shi(cic_nbits_out, cic_nbits_out_frac) downto slo(cic_nbits_out, cic_nbits_out_frac)); SIGNAL dec_dout_q : sfixed(shi(cic_nbits_out, cic_nbits_out_frac) downto slo(cic_nbits_out, cic_nbits_out_frac)); SIGNAL dec_dout_vld_i : std_logic; SIGNAL dec_dout_vld_q : std_logic; SIGNAL cfir_h_data : sfixed(shi(cfir_nbits_stages, cfir_nbits_stages_frac) downto slo(cfir_nbits_stages, cfir_nbits_stages_frac)); SIGNAL cfir_h_addr : natural range 0 to NextPowerOfTwo(cfir_ntaps)-1; SIGNAL cfir_dout_i : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL cfir_dout_q : sfixed(shi(nbits_out, nbits_out_frac) downto slo(nbits_out, nbits_out_frac)); SIGNAL cfir_h_we : std_logic; SIGNAL cfir_vld_i : std_logic; SIGNAL cfir_vld_q : std_logic; SIGNAL cfir_ready_i : std_logic; SIGNAL cfir_ready_q : std_logic; SIGNAL cfir_start_i : std_logic; SIGNAL cfir_start_q : std_logic; SIGNAL cfir_din_vld_i : std_logic; SIGNAL cfir_din_vld_q : std_logic; SIGNAL cfir_din_i : sfixed(shi(cfir_nbits_in, cfir_nbits_in_frac) downto slo(cfir_nbits_in, cfir_nbits_in_frac)); SIGNAL cfir_din_q : sfixed(shi(cfir_nbits_in, cfir_nbits_in_frac) downto slo(cfir_nbits_in, cfir_nbits_in_frac)); SIGNAL cfir_write_i : std_logic; SIGNAL cfir_write_q : std_logic; SIGNAL fifo_empty_i : std_logic; SIGNAL fifo_empty_q : std_logic; SIGNAL fifo_full_i : std_logic; SIGNAL fifo_full_q : std_logic; SIGNAL fifo_din_i : unsigned(cfir_nbits_in-1 downto 0); SIGNAL fifo_din_q : unsigned(cfir_nbits_in-1 downto 0); SIGNAL fifo_dout_i : unsigned(cfir_nbits_in-1 downto 0); SIGNAL fifo_dout_q : unsigned(cfir_nbits_in-1 downto 0); constant cfir_coef : real_array_t(0 to cfir_ntaps-1) := FilterCoef_Lowpass(cfir_ntaps, 0.40, 1.0); type h_mem_t is array (0 to cfir_ntaps-1) of sfixed(shi(cfir_nbits_stages, cfir_nbits_stages_frac) downto slo(cfir_nbits_stages, cfir_nbits_stages_frac)); function to_h_mem(coef_real : real_array_t; ntaps : integer; proto : sfixed) return h_mem_t is variable res : h_mem_t; begin for i in 0 to ntaps-1 loop res(i) := to_sfixed(coef_real(i), proto, fixed_wrap, fixed_round); end loop; return res; end to_h_mem; SIGNAL hclr_mode : std_logic; CONSTANT h_mem : h_mem_t := to_h_mem(cfir_coef, cfir_ntaps, cfir_h_data); BEGIN -- assert false report "cfir_h_addr_i'length = " & natural'image(cfir_h_addr_i'length) & "." severity note; dec_vld <= dec_dout_vld_i and dec_dout_vld_q; dec_i <= resize(dec_dout_i, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac), fixed_wrap, fixed_round); dec_q <= resize(dec_dout_q, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac), fixed_wrap, fixed_round); dout_vld <= cfir_vld_i and cfir_vld_q; dout_i <= resize(cfir_dout_i, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac), fixed_wrap, fixed_round); dout_q <= resize(cfir_dout_q, shi(nbits_out, nbits_out_frac), slo(nbits_out, nbits_out_frac), fixed_wrap, fixed_round); -- cfir_start <= dec_dout_vld_i and dec_dout_vld_q; -- Instantiate the Unit Under Test (UUT) inst_mixer: mix GENERIC MAP ( nbits_din => lo_nbits_in, nbits_din_frac => lo_nbits_in_frac, nbits_dout => lo_nbits_out, nbits_dout_frac => lo_nbits_out_frac, nbits_phase => lo_nbits_phase, nbits_freq => lo_nbits_freq ) PORT MAP ( rst => rst, clk => clk, nco_rst => lo_nco_rst, nco_en => lo_nco_en, freq_in => lo_freq_in, phase_in => lo_phase_in, din_i => din_i, din_q => din_q, dout_i => mix_dout_i, dout_q => mix_dout_q, din_vld => din_vld, dout_vld => mix_dout_vld ); inst_cic_decim_pipe_I : cic_decim_pipe GENERIC MAP ( nstages => cic_nstages, ratio => cic_ratio, scale_nbits => cic_scale_nbits, in_width => cic_nbits_in, in_width_frac => cic_nbits_in_frac, out_width => cic_nbits_out, out_width_frac => cic_nbits_out_frac ) PORT MAP ( clk => clk, rst => rst, vld_in => mix_dout_vld, din => mix_dout_i, dout => dec_dout_i, vld_out => dec_dout_vld_i ); inst_cic_decim_pipe_Q : cic_decim_pipe GENERIC MAP ( nstages => cic_nstages, ratio => cic_ratio, scale_nbits => cic_scale_nbits, in_width => cic_nbits_in, in_width_frac => cic_nbits_in_frac, out_width => cic_nbits_out, out_width_frac => cic_nbits_out_frac ) PORT MAP ( clk => clk, rst => rst, vld_in => mix_dout_vld, din => mix_dout_q, dout => dec_dout_q, vld_out => dec_dout_vld_q ); cfir_I : entity work.fir_semi_parallel GENERIC MAP ( ntaps_per_stage => cfir_ntaps_per_stage, nstages => cfir_nstages, pipe_latency => cfir_pipe_latency, nbits_in => cfir_nbits_in, nbits_in_frac => cfir_nbits_in_frac, nbits_stages => cfir_nbits_stages, nbits_stages_frac => cfir_nbits_stages_frac, nbits_out => cfir_nbits_out, nbits_out_frac => cfir_nbits_out_frac ) PORT MAP ( rst => rst, clk => clk, h_addr => cfir_h_addr, h_we => cfir_h_we, h_in => cfir_h_data, din_vld => cfir_din_vld_i, din => cfir_din_i, dout_vld => cfir_vld_i, start => cfir_start_i, rdy => cfir_ready_i, dout => cfir_dout_i ); cfir_Q : entity work.fir_semi_parallel GENERIC MAP ( ntaps_per_stage => cfir_ntaps_per_stage, nstages => cfir_nstages, pipe_latency => cfir_pipe_latency, nbits_in => cfir_nbits_in, nbits_in_frac => cfir_nbits_in_frac, nbits_stages => cfir_nbits_stages, nbits_stages_frac => cfir_nbits_stages_frac, nbits_out => cfir_nbits_out, nbits_out_frac => cfir_nbits_out_frac ) PORT MAP ( rst => rst, clk => clk, h_addr => cfir_h_addr, h_we => cfir_h_we, h_in => cfir_h_data, din_vld => cfir_din_vld_q, din => cfir_din_q, dout_vld => cfir_vld_q, start => cfir_start_q, rdy => cfir_ready_q, dout => cfir_dout_q ); cfir_din_vld_i <= not fifo_empty_i and cfir_ready_i and cfir_write_i; cfir_start_i <= fifo_empty_i and cfir_write_i; fifo_din_i <= to_unsigned(ufixed(dec_dout_i)); cfir_din_i <= sfixed(fifo_dout_i); -- cfir_din_vld_i <= dec_dout_vld_i; -- cfir_start_i <= dec_dout_vld_i; -- -- cfir_din_i <= dec_dout_i; inst_fifo_sync_i : fifo_sync GENERIC MAP ( addr_width => 1, data_width => cfir_nbits_in, almost_full_thresh => 1, almost_empty_thresh => 1 ) PORT MAP ( rst => rst, clk => clk, we => dec_dout_vld_i, re => cfir_write_i, fifo_full => fifo_full_i, fifo_empty => fifo_empty_i, fifo_afull => open, fifo_aempty => open, data_w => fifo_din_i, data_r => fifo_dout_i ); cfir_din_vld_q <= not fifo_empty_q and cfir_ready_q and cfir_write_q; cfir_start_q <= fifo_empty_q and cfir_write_q; fifo_din_q <= to_unsigned(ufixed(dec_dout_q)); cfir_din_q <= sfixed(fifo_dout_q); -- cfir_din_vld_q <= dec_dout_vld_q; -- cfir_start_q <= dec_dout_vld_q; -- -- cfir_din_q <= dec_dout_q; inst_fifo_sync_q : fifo_sync GENERIC MAP ( addr_width => 1, data_width => cfir_nbits_in, almost_full_thresh => 1, almost_empty_thresh => 1 ) PORT MAP ( rst => rst, clk => clk, we => dec_dout_vld_q, re => cfir_write_q, fifo_full => fifo_full_q, fifo_empty => fifo_empty_q, fifo_afull => open, fifo_aempty => open, data_w => fifo_din_q, data_r => fifo_dout_q ); cfir_write_logic_i: process(clk) begin if rising_edge(clk) then if rst = '1' then cfir_write_i <= '0'; elsif fifo_full_i = '1' then cfir_write_i <= '1'; elsif fifo_empty_i = '1' then cfir_write_i <= '0'; end if; end if; end process; cfir_write_logic_q: process(clk) begin if rising_edge(clk) then if rst = '1' then cfir_write_q <= '0'; elsif fifo_full_q = '1' then cfir_write_q <= '1'; elsif fifo_empty_q = '1' then cfir_write_q <= '0'; end if; end if; end process; coef_load_counter: process(clk) variable count : natural range 0 to NextPowerOfTwo(cfir_ntaps)-1; variable we : std_logic; begin if rising_edge(clk) then cfir_h_addr <= count; cfir_h_we <= we; if rst = '1' then we := '1'; hclr_mode <= '1'; count := 0; else if hclr_mode = '1' then cfir_h_data <= to_sfixed(0.0, cfir_h_data); if count /= NextPowerOfTwo(cfir_ntaps)-1 then we := '1'; count := count + 1; else count := 0; hclr_mode <= '0'; end if; else cfir_h_data <= h_mem(count); if count /= cfir_ntaps-1 then we := '1'; count := count + 1; else we := '0'; end if; end if; end if; end if; end process; END;