- added
git-svn-id: http://moon:8086/svn/vhdl/trunk@1065 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,508 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- 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.math_utility_pkg.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;
|
||||
mul_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+1;
|
||||
constant cic_nbits_out_frac : integer := nbits_out_frac+1;
|
||||
|
||||
constant cfir_mul_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,
|
||||
mul_latency => cfir_mul_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,
|
||||
mul_latency => cfir_mul_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;
|
||||
Reference in New Issue
Block a user